diff --git a/integraal/integraal-component/src/main/java/fr/boreal/component_builder/AlgorithmParameters.java b/integraal/integraal-component/src/main/java/fr/boreal/component_builder/AlgorithmParameters.java
index d547d3027649b030ac9c8f751f795b1e68c3e397..6a309e457e6514c661fe77e34b38fe6f3b9473d0 100644
--- a/integraal/integraal-component/src/main/java/fr/boreal/component_builder/AlgorithmParameters.java
+++ b/integraal/integraal-component/src/main/java/fr/boreal/component_builder/AlgorithmParameters.java
@@ -1,41 +1,30 @@
 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.externalHaltingConditions.ExternalAlgorithmHaltingConditions;
 import fr.boreal.component_builder.utils.StringUtils;
 import fr.boreal.configuration.keywords.InteGraalKeywords;
 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.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.Chase.Applier;
-import fr.boreal.configuration.keywords.InteGraalKeywords.Algorithms.Parameters.Chase.Checker;
-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.GraphOfRuleInstancesComputation;
-import fr.boreal.configuration.keywords.InteGraalKeywords.Algorithms.Parameters.Explanation.ExplanationSupportType;
-import fr.boreal.configuration.keywords.InteGraalKeywords.Algorithms.Parameters.Explanation.GraphOfRuleInstancesType;
+import fr.boreal.configuration.keywords.InteGraalKeywords.Algorithms.Parameters.Explanation.*;
+import fr.boreal.configuration.keywords.InteGraalKeywords.InternalStorageConfiguration;
 import fr.boreal.configuration.keywords.InteGraalKeywords.InternalStorageConfiguration.DBMSDriverParameters;
 import fr.boreal.configuration.keywords.InteGraalKeywords.InternalStorageConfiguration.DBType;
 import fr.boreal.configuration.keywords.InteGraalKeywords.InternalStorageConfiguration.DriverType;
 import fr.boreal.configuration.keywords.InteGraalKeywords.InternalStorageConfiguration.StorageLayout;
 import fr.boreal.configuration.parameters.IGParameter;
 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}.
@@ -49,850 +38,892 @@ import fr.lirmm.boreal.util.enumerations.EnumUtils;
  */
 public class AlgorithmParameters implements IAlgorithmParameters {
 
-	/// //////////////////////////////////////
-	/// / FIELDS
-	/// //////////////////////////////////////
-
-	static final Logger LOG = LoggerFactory.getLogger(AlgorithmParameters.class);
-	private final boolean parametereSetAtConstruction;
-
-	// Core configuration fields
-	private final Algorithms algorithm;
-	protected final String name;
-
-	// Closed parameters from enumeration
-	// chase
-	private Scheduler scheduler;
-	private Checker checker;
-	private Computer computer;
-	private Applier applier;
-	private Namer skolem;
-	private Evaluator evaluator;		// added by Michel
-	private Transformer transformer;	// added by Michel
-										// TODO check transfer of IntegralParameters to AlgorithmParameters 
-	// storage
-	private DBType dbtype;
-	private DriverType driverType;
-	private StorageLayout storageLayout;
-
-	// query rewriting
-	private Compilation compilation;
-
-	// Open parameters, with names defined from a parent enumeration
-	// database
-	private String DBMSDriverParameters_URL;
-	private String DBMSDriverParameters_PORT;
-	private String DBMSDriverParameters_DATABASE_NAME;
-	private String DBMSDriverParameters_USER_NAME;
-	private String DBMSDriverParameters_USER_PASSWORD;
-	private String DBMSDriverParameters_CLEAR_DB;
-
-	// Open parameters, with names not defined from a parent enumeration
-	private Integer max;
-	private Integer rank;
-	private Duration timeout;
-
-	// query answering
-	private Answers answers;
-	private Images images;
-
-	// Alternative for setting timeout and rank
-	private ExternalAlgorithmHaltingConditions externalHaltingConditions;
-
-	private ExplainerVerbosity explainerVerbosity;
-	private ExplainerSolver explainerSolver;
-	private GraphOfRuleInstancesComputation graphOfRuleInstancesComputation;
-	private ExplanationSupportType explanationSupportType;
-	private GraphOfRuleInstancesType graphOfRuleInstancesType;
-	private Algorithms.Parameters.Explanation explanation;
-	/////////////////////////////////////////
-	//// CONSTRUCTORS
-	/////////////////////////////////////////
-
-	/**
-	 * Constructs a new {@code AlgorithmParameters} instance.
-	 *
-	 * @param name          the name of the configuration
-	 * @param algorithmType the algorithm type (e.g., KB_CHASE, OMQA_CHASE)
-	 */
-	public AlgorithmParameters(String name, Algorithms algorithmType) {
-		this.name = name;
-		this.algorithm = algorithmType;
-		this.parametereSetAtConstruction = false;
-		initDefaultValues();
-	}
-
-	/**
-	 * Constructs a new {@code AlgorithmParameters} instance and immediately sets
-	 * parameters from the specified {@link IGParameter} object.
-	 *
-	 * @param name          the name of the configuration
-	 * @param algorithmType the algorithm type
-	 * @param params        an {@code IGParameter} containing parameter metadata
-	 */
-	public AlgorithmParameters(String name, Algorithms algorithmType, IGParameter<InteGraalKeywords, ?>... params) {
-		this.name = name;
-		this.algorithm = algorithmType;
-		initDefaultValues();
-		this.parametereSetAtConstruction = setParams(params);
-	}
-
-	/////////////////////////////////////////
-	//// OVERRIDDEN / PUBLIC METHODS
-	/////////////////////////////////////////
-
-	/**
-	 * Returns the name of the configuration concatenated with the algorithm name.
-	 *
-	 * @return the name of the configuration (e.g., "MyConfig_OMQA_CHASE")
-	 */
-	public String getName() {
-		return this.name + "_" + this.algorithm.toString();
-	}
-
-	/**
-	 * Returns the current algorithm type.
-	 *
-	 * @return the current {@link InteGraalKeywords.Algorithms} enum value
-	 */
-	public InteGraalKeywords.Algorithms getAlgorithm() {
-		return algorithm;
-	}
-
-	@Override
-	public boolean usesSaturationAlgorithm() {
-		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 usesQueryRewritingAlgorithm() {
-		return algorithm.equals(InteGraalKeywords.Algorithms.OMQ_REWRITING)
-				|| algorithm.equals(InteGraalKeywords.Algorithms.OMQA_REW);
-	}
-
-	@Override
-	public boolean usesQueryAnsweringAlgorithm() {
-		return algorithm.equals(InteGraalKeywords.Algorithms.QUERY_ANSWERING);
-	}
-
-	@Override
-	public boolean usesRuleCompilationAlgorithm() {
-		return algorithm.equals(InteGraalKeywords.Algorithms.RULE_COMPILATION) || usesQueryRewritingAlgorithm();
-	}
-
-	@Override
-	public boolean usesOMQASaturationAlgorithm() {
-		return algorithm.equals(InteGraalKeywords.Algorithms.OMQA_CHASE);
-	}
-
-	@Override
-	public boolean usesOMQARewritingAlgorithm() {
-		return algorithm.equals(InteGraalKeywords.Algorithms.OMQA_REW);
-	}
-
-	@Override
-	public boolean usesOMQAHybridAlgorithm() {
-		return algorithm.equals(InteGraalKeywords.Algorithms.QUERY_ANSWERING_VIA_HYBRID_STRATEGY);
-	}
-
-	@Override
-	public boolean usesStorage() {
-		return usesSaturationAlgorithm() || usesQueryAnsweringAlgorithm() || usesOMQASaturationAlgorithm()
-				|| usesOMQARewritingAlgorithm() || usesOMQAHybridAlgorithm();
-	}
-
-	@Override
-	public Optional<Applier> getRuleApplier() {
-		return Optional.ofNullable(applier);
-	}
-
-	@Override
-	public Optional<Scheduler> getScheduler() {
-		return Optional.ofNullable(scheduler);
-	}
-
-	@Override
-	public Optional<Checker> getCriterion() {
-		return Optional.ofNullable(checker);
-	}
-
-	@Override
-	public Optional<Computer> getComputer() {
-		return Optional.ofNullable(computer);
-	}
-
-	@Override
-	public Optional<Namer> getSkolemization() {
-		return Optional.ofNullable(skolem);
-	}
-
-	@Override
-	public Optional<Evaluator> getEvaluator() {
-		return Optional.ofNullable(evaluator);
-	}
-
-	@Override
-	public Optional<Transformer> getTransformer() {
-		return Optional.ofNullable(transformer);
-	}
-
-	@Override
-	public Optional<DBType> getStorageType() {
-		return Optional.ofNullable(dbtype);
-	}
-
-	@Override
-	public Optional<DriverType> getDBDriver() {
-		return Optional.ofNullable(driverType);
-	}
-
-	@Override
-	public Optional<StorageLayout> getDBStrategy() {
-		return Optional.ofNullable(storageLayout);
-	}
-
-	@Override
-	public Optional<Compilation> getCompilation() {
-		return Optional.ofNullable(compilation);
-	}
-
-	@Override
-	public Optional<Integer> getRank() {
-		return Optional.ofNullable(this.rank);
-	}
-
-	@Override
-	public Optional<Integer> getMax() {
-		return Optional.ofNullable(this.max);
-	}
-
-	@Override
-	public Optional<Duration> getTimeout() {
-		return Optional.ofNullable(this.timeout);
-	}
-
-	@Override
-	public Answers getResultType() {
-		return this.answers;
-	}
-
-	@Override
-	public Images getImageType() {
-		return this.images;
-	}
-
-	@Override
-	public void setResultType(Answers type) {
-		this.answers = type;
-	}
-
-	@Override
-	public void setImageType(Images type) {
-		this.images = type;
-	}
-
-	@Override
-	public boolean asksLists() {
-		return this.answers.equals(Answers.LIST);
-	}
-
-	@Override
-	public boolean asksSet() {
-		return this.answers.equals(Answers.SET);
-	}
-
-	@Override
-	public boolean asksCountOnly() {
-		return this.answers.equals(Answers.COUNT_ONLY);
-	}
-
-	@Override
-	public ExternalAlgorithmHaltingConditions getExternalHaltingConditions() {
-		if (this.externalHaltingConditions == null) {
-			this.externalHaltingConditions = ExternalAlgorithmHaltingConditions.defaultConditions();
-		}
-		return this.externalHaltingConditions;
-	}
-
-	@Override
-	public Optional<Map<DBMSDriverParameters, String>> getDBMSDriverParameters() {
-		Map<DBMSDriverParameters, String> result = new LinkedHashMap<>();
-
-		if (DBMSDriverParameters_URL != null) {
-			result.put(DBMSDriverParameters.URL, DBMSDriverParameters_URL);
-		}
-		if (DBMSDriverParameters_PORT != null) {
-			result.put(DBMSDriverParameters.PORT, DBMSDriverParameters_PORT);
-		}
-		if (DBMSDriverParameters_DATABASE_NAME != null) {
-			result.put(DBMSDriverParameters.DATABASE_NAME, DBMSDriverParameters_DATABASE_NAME);
-		}
-		if (DBMSDriverParameters_USER_NAME != null) {
-			result.put(DBMSDriverParameters.USER_NAME, DBMSDriverParameters_USER_NAME);
-		}
-		if (DBMSDriverParameters_USER_PASSWORD != null) {
-			result.put(DBMSDriverParameters.USER_PASSWORD, DBMSDriverParameters_USER_PASSWORD);
-		}
-		if (DBMSDriverParameters_CLEAR_DB != null) {
-			result.put(DBMSDriverParameters.CLEAR_DB, DBMSDriverParameters_CLEAR_DB);
-		}
-
-		if (result.isEmpty()) {
-			return Optional.empty();
-		} else {
-			return Optional.of(result);
-		}
-	}
-	
-
-	/// //////////////////////////////////////
-	/// / OVERRIDDEN / PUBLIC SETTER METHODS
-	/// //////////////////////////////////////
-
-	@Override
-	public IAlgorithmParameters setExternalHaltingConditions(ExternalAlgorithmHaltingConditions hc) {
-		if (parametereSetAtConstruction) {
-			LOG.error("parameters have been already set ; wrong usage of the method");
-		}
-		this.externalHaltingConditions = hc;
-		this.rank = externalHaltingConditions.rank();
-		this.timeout = externalHaltingConditions.timeout();
-		return this;
-	}
-
-	@Override
-	public IAlgorithmParameters setMax(Integer max) {
-		this.max = max;
-		return this;
-	}
-
-	@Override
-	public IAlgorithmParameters setRank(Integer rank) {
-		this.rank = rank;
-		return this;
-	}
-
-	@Override
-	public IAlgorithmParameters setTimeout(Duration timeout) {
-		this.timeout = timeout;
-		return this;
-	}
-
-	/**
-	 * Sets the DB storage type (e.g., PostgreSQL, H2) by matching the input string
-	 * to an enum constant and then calling {@link #setParameter(Enum)}.
-	 *
-	 * @param storageDBTypeName the name of the storage type (e.g., "H2",
-	 *                          "POSTGRESQL")
-	 * @return this {@link IAlgorithmParameters} instance for method chaining
-	 */
-	public IAlgorithmParameters setStorageType(String storageDBTypeName) {
-		return setParameter(EnumUtils.findEnumFromString(storageDBTypeName, InternalStorageConfiguration.DBType.class));
-	}
-
-	@Override
-	public IAlgorithmParameters setStorageType(DBType storage) {
-		return setParameter(storage);
-	}
-
-	/**
-	 * Sets the database driver type (e.g., "JDBC") by matching the input string to
-	 * an enum constant and then calling {@link #setParameter(Enum)}.
-	 *
-	 * @param storageDriverName the name of the driver type
-	 * @return this {@link IAlgorithmParameters} instance for method chaining
-	 */
-	public IAlgorithmParameters setDBDriver(String storageDriverName) {
-		return setParameter(
-				EnumUtils.findEnumFromString(storageDriverName, InternalStorageConfiguration.DriverType.class));
-	}
-
-	@Override
-	public IAlgorithmParameters setDBDriver(DriverType storageDriver) {
-		return setParameter(storageDriver);
-	}
-
-	/**
-	 * Sets the storage layout strategy (e.g., "DEFAULT") by matching the input
-	 * string to an enum constant and then calling {@link #setParameter(Enum)}.
-	 *
-	 * @param storageStrategyName the name of the storage layout
-	 * @return this {@link IAlgorithmParameters} instance for method chaining
-	 */
-	public IAlgorithmParameters setDBStrategy(String storageStrategyName) {
-		return setParameter(
-				EnumUtils.findEnumFromString(storageStrategyName, InternalStorageConfiguration.StorageLayout.class));
-	}
-
-	@Override
-	public IAlgorithmParameters setDBStrategy(StorageLayout storageStrategy) {
-		return setParameter(storageStrategy);
-	}
-
-
-	/**
-	 * Sets the chase rule applier by matching the input string to an enum constant
-	 * and then calling {@link #setParameter(Enum)}.
-	 *
-	 * @param applierName the name of the rule applier
-	 * @return this {@link IAlgorithmParameters} instance for method chaining
-	 */
-	public IAlgorithmParameters setRuleApplier(String applierName) {
-		return setParameter(
-				EnumUtils.findEnumFromString(applierName, InteGraalKeywords.Algorithms.Parameters.Chase.Applier.class));
-	}
-
-	@Override
-	public IAlgorithmParameters setRuleApplier(Applier applier) {
-		return setParameter(applier);
-	}
-
-	/**
-	 * Sets the scheduler by matching the input string to an enum constant and then
-	 * calling {@link #setParameter(Enum)}.
-	 *
-	 * @param scheduler the name of the scheduler
-	 * @return this {@link IAlgorithmParameters} instance for method chaining
-	 */
-	public IAlgorithmParameters setScheduler(String scheduler) {
-		return setParameter(
-				EnumUtils.findEnumFromString(scheduler, InteGraalKeywords.Algorithms.Parameters.Chase.Scheduler.class));
-	}
-
-	@Override
-	public IAlgorithmParameters setScheduler(Scheduler scheduler) {
-		return setParameter(scheduler);
-	}
-
-	/**
-	 * Sets the chase criterion (checker) by matching the input string to an enum
-	 * constant and then calling {@link #setParameter(Enum)}.
-	 *
-	 * @param criterionName the name of the chase checker
-	 * @return this {@link IAlgorithmParameters} instance for method chaining
-	 */
-	public IAlgorithmParameters setCriterion(String criterionName) {
-		return setParameter(EnumUtils.findEnumFromString(criterionName,
-				InteGraalKeywords.Algorithms.Parameters.Chase.Checker.class));
-	}
-
-	@Override
-	public IAlgorithmParameters setCriterion(Checker criterion) {
-		return setParameter(criterion);
-	}
-
-	/**
-	 * Sets the chase computer by matching the input string to an enum constant and
-	 * then calling {@link #setParameter(Enum)}.
-	 *
-	 * @param computerName the name of the chase computer
-	 * @return this {@link IAlgorithmParameters} instance for method chaining
-	 */
-	public IAlgorithmParameters setComputer(String computerName) {
-		return setParameter(EnumUtils.findEnumFromString(computerName,
-				InteGraalKeywords.Algorithms.Parameters.Chase.Computer.class));
-	}
-
-	@Override
-	public IAlgorithmParameters setComputer(Computer computer) {
-		return setParameter(computer);
-	}
-
-	/**
-	 * Sets the chase Skolemization approach by matching the input string to an enum
-	 * constant and then calling {@link #setParameter(Enum)}.
-	 *
-	 * @param skolemizationName the name of the Skolemization approach
-	 * @return this {@link IAlgorithmParameters} instance for method chaining
-	 */
-	public IAlgorithmParameters setSkolemization(String skolemizationName) {
-		return setParameter(EnumUtils.findEnumFromString(skolemizationName,
-				InteGraalKeywords.Algorithms.Parameters.Chase.Namer.class));
-	}
-
-	@Override
-	public IAlgorithmParameters setSkolemization(Namer skolemization) {
-		return setParameter(skolemization);
-	}
-
-	/**
-	 * Sets the chase evaluator by matching the input string to an enum
-	 * constant and then calling {@link #setParameter(Enum)}.
-	 *
-	 * @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,
-				InteGraalKeywords.Algorithms.Parameters.Chase.Evaluator.class));
-	}
-
-	@Override
-	public IAlgorithmParameters setEvaluator(Evaluator evaluator) {
-		return setParameter(evaluator);
-	}
-
-
-	/**
-	 * Sets the chase transformer by matching the input string to an enum
-	 * constant and then calling {@link #setParameter(Enum)}.
-	 *
-	 * @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,
-				InteGraalKeywords.Algorithms.Parameters.Chase.Transformer.class));
-	}
-
-	@Override
-	public IAlgorithmParameters setTransformer(Transformer transformer) {
-		return setParameter(transformer);
-	}
-
-	
-	/**
-	 * Sets the compilation approach (e.g., "DEFAULT") by matching the input string
-	 * to an enum constant and then calling {@link #setParameter(Enum)}.
-	 *
-	 * @param compilationName the name of the compilation type
-	 * @return this {@link IAlgorithmParameters} instance for method chaining
-	 */
-	public IAlgorithmParameters setCompilation(String compilationName) {
-		return setParameter(EnumUtils.findEnumFromString(compilationName,
-				InteGraalKeywords.Algorithms.Parameters.Compilation.class));
-	}
-
-	@Override
-	public IAlgorithmParameters setCompilation(Compilation compilation) {
-		return setParameter(compilation);
-	}
-
-	/**
-	 * Sets a DBMS driver parameter based on the provided parameter name and value.
-	 * The parameter name is mapped to an enum instance of
-	 * {@link DBMSDriverParameters}, and then the appropriate field in this class is
-	 * updated.
-	 *
-	 * @param paramName  the name of the DBMS driver parameter, e.g., "URL" or
-	 *                   "PORT"
-	 * @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)
-	 */
-	public void setDBMSDriverParameters(String paramName, String paramValue) {
-		setDBMSDriverParameters(EnumUtils.findEnumFromString(paramName, DBMSDriverParameters.class), paramValue);
-	}
-
-	@Override
-	public IAlgorithmParameters setDBMSDriverParameters(DBMSDriverParameters paramName, String value) {
-		switch (paramName) {
-		case DATABASE_NAME -> this.DBMSDriverParameters_DATABASE_NAME = value;
-		case PORT -> this.DBMSDriverParameters_PORT = value;
-		case URL -> this.DBMSDriverParameters_URL = value;
-		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);
-		}
-		return this;
-	}
-
-	/////////////////////////////////////////
-	//// PRIVATE / HELPER METHODS
-	/////////////////////////////////////////
-
-	/**
-	 * Iterates over the provided {@code params}, handling each based on its
-	 * category (enumeration, open parameter from an enumeration, or open
-	 * parameter).
-	 *
-	 * @param params one or more {@link IGParameter} objects that define parameter
-	 *               names and values
-	 * @return {@code true} if all parameters were handled successfully;
-	 *         {@code false} if an unrecognized parameter was encountered
-	 */
-	@SuppressWarnings("unchecked")
-	private boolean setParams(IGParameter<InteGraalKeywords, ?>... params) {
-		for (var param : params) {
-			switch (param.name()) {
-			// 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.,
-			// DBConnectionParams)
-			case InteGraalKeywords k when !k.isEnumeration() && k.getParentEnum().isPresent() ->
-				setOpenParameterFromEnumeration(k.getParentEnum().get(), param.name().toString(),
-						param.value().toString());
-
-			// open set of values (e.g., Rank, Timeout)
-			case InteGraalKeywords k when !k.isEnumeration() && !k.getParentEnum().isPresent() ->
-				setOpenParameter(k, param.value());
-
-			default -> {
-				LOG.error("Cannot handle parameter " + param);
-				return false;
-			}
-			}
-		}
-		return true;
-	}
-
-	/**
-	 * Sets the value of a parameter based on the provided enum constant. This
-	 * 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
-	 * is expected to match the simple name of the enum's class, with the first
-	 * letter lowercased (following Java naming conventions)
-	 *
-	 * @param enumValue The enum constant to set as the value of the corresponding
-	 *                  field. The enum's class simple name (lowercased) should
-	 *                  match the name of the field in this class.
-	 * @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
-	 *                          match the expected naming convention.
-	 * @see Field#setAccessible(boolean)
-	 */
-	public IAlgorithmParameters setParameter(Enum<?> enumValue) {
-		LOG.debug("Setting parameter {} for {}", enumValue, this.name);
-		validateParameter(enumValue);
-		String fieldName = enumValue.getClass().getSimpleName();
-		try {
-			Field field = null;
-			for (Field f : this.getClass().getDeclaredFields()) {
-				if (fieldName.equalsIgnoreCase(f.getName())) {
-					field = f;
-					break;
-				}
-			}
-			if (field == null) {
-				LOG.error("Cannot set parameter {}", enumValue);
-				throw new RuntimeException(
-						String.format("[%s::setParameter] Cannot set parameter: %s.", this.getClass(), enumValue));
-			} else {
-				field.setAccessible(true);
-				field.set(this, enumValue);
-			}
-		} catch (IllegalAccessException e) {
-			LOG.error("Failed to set parameter: {}\n{}", fieldName, e.getMessage());
-			throw new RuntimeException(
-					String.format("[%s::setParameter] Failed to set parameter: %s.", this.getClass(), fieldName), e);
-		}
-		return this;
-	}
-
-	/**
-	 * Sets an open parameter (defined within a known enumeration) by mapping the
-	 * given {@code propertyName} to the appropriate enum constant in
-	 * {@code className}, and assigning the provided {@code value}.
-	 * <p>
-	 * Currently, this is primarily used for {@code DBMSDriverParameters}.
-	 * </p>
-	 *
-	 * @param className    the enum's class, e.g.,
-	 *                     {@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
-	 * @throws IllegalArgumentException if {@code propertyName} does not match any
-	 *                                  known constant in {@code className}
-	 */
-	public IAlgorithmParameters setOpenParameterFromEnumeration(Class<? extends Enum<?>> className, String propertyName,
-			String value) {
-		LOG.debug("Setting parameter {} for {} with value {} for {} ", propertyName, className.getSimpleName(), value,
-				this.name);
-
-		switch (className.getSimpleName().toUpperCase()) {
-		case "DBMSDRIVERPARAMETERS" -> setDBMSDriverParameters(propertyName, value);
-		default -> throw new IllegalArgumentException("Unexpected value: " + className);
-		}
-		return this;
-	}
-
-	/**
-	 * Similar to {@link #setOpenParameterFromEnumeration(Class, String, String)},
-	 * but takes an {@code enumName} instead of the enum {@code className}. This
-	 * method is used to handle open parameters where the parent enumeration is
-	 * already determined.
-	 *
-	 * @param enumName     the enumeration constant representing the parameter
-	 *                     category
-	 * @param propertyName the name of the specific parameter within that category
-	 * @param value        the string value to assign to the parameter
-	 * @return this {@link IAlgorithmParameters} instance for method chaining
-	 * @throws IllegalArgumentException if {@code propertyName} does not match any
-	 *                                  recognized constant for the given
-	 *                                  {@code enumName}
-	 */
-	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()) {
-		case "DBMSDRIVERPARAMETERS" -> setDBMSDriverParameters(propertyName, value);
-		default -> throw new IllegalArgumentException("Unexpected value: " + enumName);
-		}
-		return this;
-	}
-
-	/**
-	 * Sets an open parameter (one that is not tied to a closed enumeration of
-	 * values) by matching its name to one of the fields declared in this class. If
-	 * found, the field is updated with the provided {@code value}.
-	 *
-	 * @param k     the keyword representing the parameter name
-	 * @param value the value to set (type {@code Object} because parameters can
-	 *              vary)
-	 * @return this {@link IAlgorithmParameters} instance for method chaining
-	 * @throws RuntimeException if the parameter field cannot be found or set
-	 * @see Field#setAccessible(boolean)
-	 */
-	public IAlgorithmParameters setOpenParameter(InteGraalKeywords k, Object value) {
-		LOG.debug("Setting parameter {} with value {} for {}", k, value, this.name);
-		String fieldName = k.name();
-		try {
-			Field field = null;
-			for (Field f : this.getClass().getDeclaredFields()) {
-				if (fieldName.equalsIgnoreCase(f.getName())) {
-					field = f;
-					break;
-				}
-			}
-			if (field == null) {
-				LOG.error("Cannot set parameter {}", k);
-				throw new RuntimeException(
-						String.format("[%s::setParameter] Cannot set parameter: %s.", this.getClass(), value));
-			} else {
-				field.setAccessible(true);
-				field.set(this, value);
-			}
-		} catch (IllegalAccessException e) {
-			LOG.error("Failed to set parameter: {}\n{}", k, e.getMessage());
-			throw new RuntimeException(
-					String.format("[%s::setParameter] Failed to set parameter: %s.", this.getClass(), k), e);
-		}
-		return this;
-	}
-
-	/**
-	 * Validates whether the specified enum value is allowable based on the current
-	 * algorithm's capabilities. For example, chase parameters cannot be used with
-	 * an algorithm that does not support chase.
-	 *
-	 * @param enumValue the enum constant to validate
-	 * @throws IllegalArgumentException if the enum value is incompatible with the
-	 *                                  current algorithm
-	 */
-	private void validateParameter(Enum<?> enumValue) {
-		if (enumValue.getClass().getEnclosingClass() == InteGraalKeywords.Algorithms.Parameters.Chase.class
-				&& !usesSaturationAlgorithm()) {
-			throw new IllegalArgumentException(
-					"Chase parameter " + enumValue + " cannot be set for " + getAlgorithm() + " algorithms.");
-		}
-
-		if (enumValue.getClass().getEnclosingClass() == InteGraalKeywords.Algorithms.Parameters.Compilation.class
-				&& !usesRuleCompilationAlgorithm()) {
-			throw new IllegalArgumentException(
-					"Compilation parameter " + enumValue + " cannot be set for " + getAlgorithm() + " algorithms.");
-		}
-
-		if (enumValue.getClass().getEnclosingClass() == InteGraalKeywords.InternalStorageConfiguration.class
-				&& !usesStorage()) {
-			throw new IllegalArgumentException(
-					"Storage parameter " + enumValue + " cannot be set for " + getAlgorithm() + " algorithms.");
-		}
-	}
-
-	private void initDefaultValues() {
-
-		this.answers = Answers.SET;
-
-		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;
-	}
+    /// //////////////////////////////////////
+    /// / FIELDS
+    /// //////////////////////////////////////
+
+    static final Logger LOG = LoggerFactory.getLogger(AlgorithmParameters.class);
+    private final boolean parametereSetAtConstruction;
+
+    // Core configuration fields
+    private final Algorithms algorithm;
+    protected final String name;
+
+    // Closed parameters from enumeration
+    // chase
+    private Scheduler scheduler;
+    private Checker checker;
+    private Computer computer;
+    private Applier applier;
+    private Namer skolem;
+    private Evaluator evaluator;        // added by Michel
+    private Transformer transformer;    // added by Michel
+    // TODO check transfer of IntegralParameters to AlgorithmParameters
+    // storage
+    private DBType dbtype;
+    private DriverType driverType;
+    private StorageLayout storageLayout;
+
+    // query rewriting
+    private Compilation compilation;
+
+    // Open parameters, with names defined from a parent enumeration
+    // database
+    private String DBMSDriverParameters_URL;
+    private String DBMSDriverParameters_PORT;
+    private String DBMSDriverParameters_DATABASE_NAME;
+    private String DBMSDriverParameters_USER_NAME;
+    private String DBMSDriverParameters_USER_PASSWORD;
+    private String DBMSDriverParameters_CLEAR_DB;
+
+    // Open parameters, with names not defined from a parent enumeration
+    private Integer max;
+    private Integer rank;
+    private Duration timeout;
+
+    // query answering
+    private Answers answers;
+    private Images images;
+
+    // Alternative for setting timeout and rank
+    private ExternalAlgorithmHaltingConditions externalHaltingConditions;
+
+    private ExplainerVerbosity explainerVerbosity;
+    private ExplainerSolver explainerSolver;
+    private GraphOfRuleInstancesComputation graphOfRuleInstancesComputation;
+    private ExplanationSupportType explanationSupportType;
+    private GraphOfRuleInstancesType graphOfRuleInstancesType;
+    private Algorithms.Parameters.Explanation explanation;
+    private Integer GSATSolverParameters_SMART_SOLVER_TRESHOLD;
+    private String GSATSolverParameters_MARCO_PATH_TO_EXECUTABLE;
+    /////////////////////////////////////////
+    //// CONSTRUCTORS
+    /////////////////////////////////////////
+
+    /**
+     * Constructs a new {@code AlgorithmParameters} instance.
+     *
+     * @param name          the name of the configuration
+     * @param algorithmType the algorithm type (e.g., KB_CHASE, OMQA_CHASE)
+     */
+    public AlgorithmParameters(String name, Algorithms algorithmType) {
+        this.name = name;
+        this.algorithm = algorithmType;
+        this.parametereSetAtConstruction = false;
+        initDefaultValues();
+    }
+
+    /**
+     * Constructs a new {@code AlgorithmParameters} instance and immediately sets
+     * parameters from the specified {@link IGParameter} object.
+     *
+     * @param name          the name of the configuration
+     * @param algorithmType the algorithm type
+     * @param params        an {@code IGParameter} containing parameter metadata
+     */
+    public AlgorithmParameters(String name, Algorithms algorithmType, IGParameter<InteGraalKeywords, ?>... params) {
+        this.name = name;
+        this.algorithm = algorithmType;
+        initDefaultValues();
+        this.parametereSetAtConstruction = setParams(params);
+    }
+
+    /////////////////////////////////////////
+    //// OVERRIDDEN / PUBLIC METHODS
+    /////////////////////////////////////////
+
+    /**
+     * Returns the name of the configuration concatenated with the algorithm name.
+     *
+     * @return the name of the configuration (e.g., "MyConfig_OMQA_CHASE")
+     */
+    public String getName() {
+        return this.name + "_" + this.algorithm.toString();
+    }
+
+    /**
+     * Returns the current algorithm type.
+     *
+     * @return the current {@link InteGraalKeywords.Algorithms} enum value
+     */
+    public InteGraalKeywords.Algorithms getAlgorithm() {
+        return algorithm;
+    }
+
+    @Override
+    public boolean usesSaturationAlgorithm() {
+        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 usesQueryRewritingAlgorithm() {
+        return algorithm.equals(InteGraalKeywords.Algorithms.OMQ_REWRITING)
+                || algorithm.equals(InteGraalKeywords.Algorithms.OMQA_REW);
+    }
+
+    @Override
+    public boolean usesQueryAnsweringAlgorithm() {
+        return algorithm.equals(InteGraalKeywords.Algorithms.QUERY_ANSWERING);
+    }
+
+    @Override
+    public boolean usesRuleCompilationAlgorithm() {
+        return algorithm.equals(InteGraalKeywords.Algorithms.RULE_COMPILATION) || usesQueryRewritingAlgorithm();
+    }
+
+    @Override
+    public boolean usesOMQASaturationAlgorithm() {
+        return algorithm.equals(InteGraalKeywords.Algorithms.OMQA_CHASE);
+    }
+
+    @Override
+    public boolean usesOMQARewritingAlgorithm() {
+        return algorithm.equals(InteGraalKeywords.Algorithms.OMQA_REW);
+    }
+
+    @Override
+    public boolean usesOMQAHybridAlgorithm() {
+        return algorithm.equals(InteGraalKeywords.Algorithms.QUERY_ANSWERING_VIA_HYBRID_STRATEGY);
+    }
+
+    @Override
+    public boolean usesStorage() {
+        return usesSaturationAlgorithm() || usesQueryAnsweringAlgorithm() || usesOMQASaturationAlgorithm()
+                || usesOMQARewritingAlgorithm() || usesOMQAHybridAlgorithm();
+    }
+
+    @Override
+    public Optional<Applier> getRuleApplier() {
+        return Optional.ofNullable(applier);
+    }
+
+    @Override
+    public Optional<Scheduler> getScheduler() {
+        return Optional.ofNullable(scheduler);
+    }
+
+    @Override
+    public Optional<Checker> getCriterion() {
+        return Optional.ofNullable(checker);
+    }
+
+    @Override
+    public Optional<Computer> getComputer() {
+        return Optional.ofNullable(computer);
+    }
+
+    @Override
+    public Optional<Namer> getSkolemization() {
+        return Optional.ofNullable(skolem);
+    }
+
+    @Override
+    public Optional<Evaluator> getEvaluator() {
+        return Optional.ofNullable(evaluator);
+    }
+
+    @Override
+    public Optional<Transformer> getTransformer() {
+        return Optional.ofNullable(transformer);
+    }
+
+    @Override
+    public Optional<DBType> getStorageType() {
+        return Optional.ofNullable(dbtype);
+    }
+
+    @Override
+    public Optional<DriverType> getDBDriver() {
+        return Optional.ofNullable(driverType);
+    }
+
+    @Override
+    public Optional<StorageLayout> getDBStrategy() {
+        return Optional.ofNullable(storageLayout);
+    }
+
+    @Override
+    public Optional<Compilation> getCompilation() {
+        return Optional.ofNullable(compilation);
+    }
+
+    @Override
+    public Optional<Integer> getRank() {
+        return Optional.ofNullable(this.rank);
+    }
+
+    @Override
+    public Optional<Integer> getMax() {
+        return Optional.ofNullable(this.max);
+    }
+
+    @Override
+    public Optional<Duration> getTimeout() {
+        return Optional.ofNullable(this.timeout);
+    }
+
+    @Override
+    public Answers getResultType() {
+        return this.answers;
+    }
+
+    @Override
+    public Images getImageType() {
+        return this.images;
+    }
+
+    @Override
+    public void setResultType(Answers type) {
+        this.answers = type;
+    }
+
+    @Override
+    public void setImageType(Images type) {
+        this.images = type;
+    }
+
+    @Override
+    public boolean asksLists() {
+        return this.answers.equals(Answers.LIST);
+    }
+
+    @Override
+    public boolean asksSet() {
+        return this.answers.equals(Answers.SET);
+    }
+
+    @Override
+    public boolean asksCountOnly() {
+        return this.answers.equals(Answers.COUNT_ONLY);
+    }
+
+    @Override
+    public ExternalAlgorithmHaltingConditions getExternalHaltingConditions() {
+        if (this.externalHaltingConditions == null) {
+            this.externalHaltingConditions = ExternalAlgorithmHaltingConditions.defaultConditions();
+        }
+        return this.externalHaltingConditions;
+    }
+
+    @Override
+    public Optional<Map<DBMSDriverParameters, String>> getDBMSDriverParameters() {
+        Map<DBMSDriverParameters, String> result = new LinkedHashMap<>();
+
+        if (DBMSDriverParameters_URL != null) {
+            result.put(DBMSDriverParameters.URL, DBMSDriverParameters_URL);
+        }
+        if (DBMSDriverParameters_PORT != null) {
+            result.put(DBMSDriverParameters.PORT, DBMSDriverParameters_PORT);
+        }
+        if (DBMSDriverParameters_DATABASE_NAME != null) {
+            result.put(DBMSDriverParameters.DATABASE_NAME, DBMSDriverParameters_DATABASE_NAME);
+        }
+        if (DBMSDriverParameters_USER_NAME != null) {
+            result.put(DBMSDriverParameters.USER_NAME, DBMSDriverParameters_USER_NAME);
+        }
+        if (DBMSDriverParameters_USER_PASSWORD != null) {
+            result.put(DBMSDriverParameters.USER_PASSWORD, DBMSDriverParameters_USER_PASSWORD);
+        }
+        if (DBMSDriverParameters_CLEAR_DB != null) {
+            result.put(DBMSDriverParameters.CLEAR_DB, DBMSDriverParameters_CLEAR_DB);
+        }
+
+        if (result.isEmpty()) {
+            return Optional.empty();
+        } else {
+            return Optional.of(result);
+        }
+    }
+
+
+    /// //////////////////////////////////////
+    /// / OVERRIDDEN / PUBLIC SETTER METHODS
+    /// //////////////////////////////////////
+
+    @Override
+    public IAlgorithmParameters setExternalHaltingConditions(ExternalAlgorithmHaltingConditions hc) {
+        if (parametereSetAtConstruction) {
+            LOG.error("parameters have been already set ; wrong usage of the method");
+        }
+        this.externalHaltingConditions = hc;
+        this.rank = externalHaltingConditions.rank();
+        this.timeout = externalHaltingConditions.timeout();
+        return this;
+    }
+
+    @Override
+    public IAlgorithmParameters setMax(Integer max) {
+        this.max = max;
+        return this;
+    }
+
+    @Override
+    public IAlgorithmParameters setRank(Integer rank) {
+        this.rank = rank;
+        return this;
+    }
+
+    @Override
+    public IAlgorithmParameters setTimeout(Duration timeout) {
+        this.timeout = timeout;
+        return this;
+    }
+
+    /**
+     * Sets the DB storage type (e.g., PostgreSQL, H2) by matching the input string
+     * to an enum constant and then calling {@link #setParameter(Enum)}.
+     *
+     * @param storageDBTypeName the name of the storage type (e.g., "H2",
+     *                          "POSTGRESQL")
+     * @return this {@link IAlgorithmParameters} instance for method chaining
+     */
+    public IAlgorithmParameters setStorageType(String storageDBTypeName) {
+        return setParameter(EnumUtils.findEnumFromString(storageDBTypeName, InternalStorageConfiguration.DBType.class));
+    }
+
+    @Override
+    public IAlgorithmParameters setStorageType(DBType storage) {
+        return setParameter(storage);
+    }
+
+    /**
+     * Sets the database driver type (e.g., "JDBC") by matching the input string to
+     * an enum constant and then calling {@link #setParameter(Enum)}.
+     *
+     * @param storageDriverName the name of the driver type
+     * @return this {@link IAlgorithmParameters} instance for method chaining
+     */
+    public IAlgorithmParameters setDBDriver(String storageDriverName) {
+        return setParameter(
+                EnumUtils.findEnumFromString(storageDriverName, InternalStorageConfiguration.DriverType.class));
+    }
+
+    @Override
+    public IAlgorithmParameters setDBDriver(DriverType storageDriver) {
+        return setParameter(storageDriver);
+    }
+
+    /**
+     * Sets the storage layout strategy (e.g., "DEFAULT") by matching the input
+     * string to an enum constant and then calling {@link #setParameter(Enum)}.
+     *
+     * @param storageStrategyName the name of the storage layout
+     * @return this {@link IAlgorithmParameters} instance for method chaining
+     */
+    public IAlgorithmParameters setDBStrategy(String storageStrategyName) {
+        return setParameter(
+                EnumUtils.findEnumFromString(storageStrategyName, InternalStorageConfiguration.StorageLayout.class));
+    }
+
+    @Override
+    public IAlgorithmParameters setDBStrategy(StorageLayout storageStrategy) {
+        return setParameter(storageStrategy);
+    }
+
+
+    /**
+     * Sets the chase rule applier by matching the input string to an enum constant
+     * and then calling {@link #setParameter(Enum)}.
+     *
+     * @param applierName the name of the rule applier
+     * @return this {@link IAlgorithmParameters} instance for method chaining
+     */
+    public IAlgorithmParameters setRuleApplier(String applierName) {
+        return setParameter(
+                EnumUtils.findEnumFromString(applierName, InteGraalKeywords.Algorithms.Parameters.Chase.Applier.class));
+    }
+
+    @Override
+    public IAlgorithmParameters setRuleApplier(Applier applier) {
+        return setParameter(applier);
+    }
+
+    /**
+     * Sets the scheduler by matching the input string to an enum constant and then
+     * calling {@link #setParameter(Enum)}.
+     *
+     * @param scheduler the name of the scheduler
+     * @return this {@link IAlgorithmParameters} instance for method chaining
+     */
+    public IAlgorithmParameters setScheduler(String scheduler) {
+        return setParameter(
+                EnumUtils.findEnumFromString(scheduler, InteGraalKeywords.Algorithms.Parameters.Chase.Scheduler.class));
+    }
+
+    @Override
+    public IAlgorithmParameters setScheduler(Scheduler scheduler) {
+        return setParameter(scheduler);
+    }
+
+    /**
+     * Sets the chase criterion (checker) by matching the input string to an enum
+     * constant and then calling {@link #setParameter(Enum)}.
+     *
+     * @param criterionName the name of the chase checker
+     * @return this {@link IAlgorithmParameters} instance for method chaining
+     */
+    public IAlgorithmParameters setCriterion(String criterionName) {
+        return setParameter(EnumUtils.findEnumFromString(criterionName,
+                InteGraalKeywords.Algorithms.Parameters.Chase.Checker.class));
+    }
+
+    @Override
+    public IAlgorithmParameters setCriterion(Checker criterion) {
+        return setParameter(criterion);
+    }
+
+    /**
+     * Sets the chase computer by matching the input string to an enum constant and
+     * then calling {@link #setParameter(Enum)}.
+     *
+     * @param computerName the name of the chase computer
+     * @return this {@link IAlgorithmParameters} instance for method chaining
+     */
+    public IAlgorithmParameters setComputer(String computerName) {
+        return setParameter(EnumUtils.findEnumFromString(computerName,
+                InteGraalKeywords.Algorithms.Parameters.Chase.Computer.class));
+    }
+
+    @Override
+    public IAlgorithmParameters setComputer(Computer computer) {
+        return setParameter(computer);
+    }
+
+    /**
+     * Sets the chase Skolemization approach by matching the input string to an enum
+     * constant and then calling {@link #setParameter(Enum)}.
+     *
+     * @param skolemizationName the name of the Skolemization approach
+     * @return this {@link IAlgorithmParameters} instance for method chaining
+     */
+    public IAlgorithmParameters setSkolemization(String skolemizationName) {
+        return setParameter(EnumUtils.findEnumFromString(skolemizationName,
+                InteGraalKeywords.Algorithms.Parameters.Chase.Namer.class));
+    }
+
+    @Override
+    public IAlgorithmParameters setSkolemization(Namer skolemization) {
+        return setParameter(skolemization);
+    }
+
+    /**
+     * Sets the chase evaluator by matching the input string to an enum
+     * constant and then calling {@link #setParameter(Enum)}.
+     *
+     * @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,
+                InteGraalKeywords.Algorithms.Parameters.Chase.Evaluator.class));
+    }
+
+    @Override
+    public IAlgorithmParameters setEvaluator(Evaluator evaluator) {
+        return setParameter(evaluator);
+    }
+
+
+    /**
+     * Sets the chase transformer by matching the input string to an enum
+     * constant and then calling {@link #setParameter(Enum)}.
+     *
+     * @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,
+                InteGraalKeywords.Algorithms.Parameters.Chase.Transformer.class));
+    }
+
+    @Override
+    public IAlgorithmParameters setTransformer(Transformer transformer) {
+        return setParameter(transformer);
+    }
+
+
+    /**
+     * Sets the compilation approach (e.g., "DEFAULT") by matching the input string
+     * to an enum constant and then calling {@link #setParameter(Enum)}.
+     *
+     * @param compilationName the name of the compilation type
+     * @return this {@link IAlgorithmParameters} instance for method chaining
+     */
+    public IAlgorithmParameters setCompilation(String compilationName) {
+        return setParameter(EnumUtils.findEnumFromString(compilationName,
+                InteGraalKeywords.Algorithms.Parameters.Compilation.class));
+    }
+
+    @Override
+    public IAlgorithmParameters setCompilation(Compilation compilation) {
+        return setParameter(compilation);
+    }
+
+    /**
+     * Sets a DBMS driver parameter based on the provided parameter name and value.
+     * The parameter name is mapped to an enum instance of
+     * {@link DBMSDriverParameters}, and then the appropriate field in this class is
+     * updated.
+     *
+     * @param paramName  the name of the DBMS driver parameter, e.g., "URL" or
+     *                   "PORT"
+     * @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)
+     */
+    public void setDBMSDriverParameters(String paramName, String paramValue) {
+        setDBMSDriverParameters(EnumUtils.findEnumFromString(paramName, DBMSDriverParameters.class), paramValue);
+    }
+
+    public void setGSATSolverParameters(String paramName, String paramValue) {
+        setGSATSolverParameters(EnumUtils.findEnumFromString(paramName, GSATSolverParameters.class), paramValue);
+    }
+
+
+    @Override
+    public IAlgorithmParameters setDBMSDriverParameters(DBMSDriverParameters paramName, String value) {
+        switch (paramName) {
+            case DATABASE_NAME -> this.DBMSDriverParameters_DATABASE_NAME = value;
+            case PORT -> this.DBMSDriverParameters_PORT = value;
+            case URL -> this.DBMSDriverParameters_URL = value;
+            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);
+        }
+        return this;
+    }
+
+
+    @Override
+    public IAlgorithmParameters setGSATSolverParameters(GSATSolverParameters paramName, String value) {
+        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);
+        }
+        return this;
+    }
+
+    @Override
+    public Optional<String> getMARCOPathToExecutable() {
+        return Optional.ofNullable(this.GSATSolverParameters_MARCO_PATH_TO_EXECUTABLE);
+    }
+
+    @Override
+    public IAlgorithmParameters setMARCOPathToExecutable(String pathtoExecutable) {
+        this.GSATSolverParameters_MARCO_PATH_TO_EXECUTABLE = pathtoExecutable;
+        return this;
+    }
+
+    /////////////////////////////////////////
+    //// PRIVATE / HELPER METHODS
+    /////////////////////////////////////////
+
+    /**
+     * Iterates over the provided {@code params}, handling each based on its
+     * category (enumeration, open parameter from an enumeration, or open
+     * parameter).
+     *
+     * @param params one or more {@link IGParameter} objects that define parameter
+     *               names and values
+     * @return {@code true} if all parameters were handled successfully;
+     * {@code false} if an unrecognized parameter was encountered
+     */
+    @SuppressWarnings("unchecked")
+    private boolean setParams(IGParameter<InteGraalKeywords, ?>... params) {
+        for (var param : params) {
+            switch (param.name()) {
+                // 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.,
+                // DBConnectionParams)
+                case InteGraalKeywords k when !k.isEnumeration() && k.getParentEnum().isPresent() ->
+                        setOpenParameterFromEnumeration(k.getParentEnum().get(), param.name().toString(),
+                                param.value().toString());
+
+                // open set of values (e.g., Rank, Timeout)
+                case InteGraalKeywords k when !k.isEnumeration() && !k.getParentEnum().isPresent() ->
+                        setOpenParameter(k, param.value());
+
+                default -> {
+                    LOG.error("Cannot handle parameter " + param);
+                    return false;
+                }
+            }
+        }
+        return true;
+    }
+
+    /**
+     * Sets the value of a parameter based on the provided enum constant. This
+     * 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
+     * is expected to match the simple name of the enum's class, with the first
+     * letter lowercased (following Java naming conventions)
+     *
+     * @param enumValue The enum constant to set as the value of the corresponding
+     *                  field. The enum's class simple name (lowercased) should
+     *                  match the name of the field in this class.
+     * @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
+     *                          match the expected naming convention.
+     * @see Field#setAccessible(boolean)
+     */
+    public IAlgorithmParameters setParameter(Enum<?> enumValue) {
+        LOG.debug("Setting parameter {} for {}", enumValue, this.name);
+        validateParameter(enumValue);
+        String fieldName = enumValue.getClass().getSimpleName();
+        try {
+            Field field = null;
+            for (Field f : this.getClass().getDeclaredFields()) {
+                if (fieldName.equalsIgnoreCase(f.getName())) {
+                    field = f;
+                    break;
+                }
+            }
+            if (field == null) {
+                LOG.error("Cannot set parameter {}", enumValue);
+                throw new RuntimeException(
+                        String.format("[%s::setParameter] Cannot set parameter: %s.", this.getClass(), enumValue));
+            } else {
+                field.setAccessible(true);
+                field.set(this, enumValue);
+            }
+        } catch (IllegalAccessException e) {
+            LOG.error("Failed to set parameter: {}\n{}", fieldName, e.getMessage());
+            throw new RuntimeException(
+                    String.format("[%s::setParameter] Failed to set parameter: %s.", this.getClass(), fieldName), e);
+        }
+        return this;
+    }
+
+    /**
+     * Sets an open parameter (defined within a known enumeration) by mapping the
+     * given {@code propertyName} to the appropriate enum constant in
+     * {@code className}, and assigning the provided {@code value}.
+     * <p>
+     * Currently, this is primarily used for {@code DBMSDriverParameters}.
+     * </p>
+     *
+     * @param className    the enum's class, e.g.,
+     *                     {@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
+     * @throws IllegalArgumentException if {@code propertyName} does not match any
+     *                                  known constant in {@code className}
+     */
+    public IAlgorithmParameters setOpenParameterFromEnumeration(Class<? extends Enum<?>> className, String propertyName,
+                                                                String value) {
+        LOG.debug("Setting parameter {} for {} with value {} for {} ", propertyName, className.getSimpleName(), value,
+                this.name);
+
+        switch (className.getSimpleName().toUpperCase()) {
+            case "DBMSDRIVERPARAMETERS" -> setDBMSDriverParameters(propertyName, value);
+            case "GSATSOLVERPARAMETERS" -> setGSATSolverParameters(propertyName, value);
+            default -> throw new IllegalArgumentException("Unexpected value: " + className);
+        }
+        return this;
+    }
+
+    /**
+     * Similar to {@link #setOpenParameterFromEnumeration(Class, String, String)},
+     * but takes an {@code enumName} instead of the enum {@code className}. This
+     * method is used to handle open parameters where the parent enumeration is
+     * already determined.
+     *
+     * @param enumName     the enumeration constant representing the parameter
+     *                     category
+     * @param propertyName the name of the specific parameter within that category
+     * @param value        the string value to assign to the parameter
+     * @return this {@link IAlgorithmParameters} instance for method chaining
+     * @throws IllegalArgumentException if {@code propertyName} does not match any
+     *                                  recognized constant for the given
+     *                                  {@code enumName}
+     */
+    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()) {
+            case "DBMSDRIVERPARAMETERS" -> setDBMSDriverParameters(propertyName, value);
+            default -> throw new IllegalArgumentException("Unexpected value: " + enumName);
+        }
+        return this;
+    }
+
+    /**
+     * Sets an open parameter (one that is not tied to a closed enumeration of
+     * values) by matching its name to one of the fields declared in this class. If
+     * found, the field is updated with the provided {@code value}.
+     *
+     * @param k     the keyword representing the parameter name
+     * @param value the value to set (type {@code Object} because parameters can
+     *              vary)
+     * @return this {@link IAlgorithmParameters} instance for method chaining
+     * @throws RuntimeException if the parameter field cannot be found or set
+     * @see Field#setAccessible(boolean)
+     */
+    public IAlgorithmParameters setOpenParameter(InteGraalKeywords k, Object value) {
+        LOG.debug("Setting parameter {} with value {} for {}", k, value, this.name);
+        String fieldName = k.name();
+        try {
+            Field field = null;
+            for (Field f : this.getClass().getDeclaredFields()) {
+                if (fieldName.equalsIgnoreCase(f.getName())) {
+                    field = f;
+                    break;
+                }
+            }
+            if (field == null) {
+                LOG.error("Cannot set parameter {}", k);
+                throw new RuntimeException(
+                        String.format("[%s::setParameter] Cannot set parameter: %s.", this.getClass(), value));
+            } else {
+                field.setAccessible(true);
+                field.set(this, value);
+            }
+        } catch (IllegalAccessException e) {
+            LOG.error("Failed to set parameter: {}\n{}", k, e.getMessage());
+            throw new RuntimeException(
+                    String.format("[%s::setParameter] Failed to set parameter: %s.", this.getClass(), k), e);
+        }
+        return this;
+    }
+
+    /**
+     * Validates whether the specified enum value is allowable based on the current
+     * algorithm's capabilities. For example, chase parameters cannot be used with
+     * an algorithm that does not support chase.
+     *
+     * @param enumValue the enum constant to validate
+     * @throws IllegalArgumentException if the enum value is incompatible with the
+     *                                  current algorithm
+     */
+    private void validateParameter(Enum<?> enumValue) {
+        if (enumValue.getClass().getEnclosingClass() == InteGraalKeywords.Algorithms.Parameters.Chase.class
+                && !usesSaturationAlgorithm()) {
+            throw new IllegalArgumentException(
+                    "Chase parameter " + enumValue + " cannot be set for " + getAlgorithm() + " algorithms.");
+        }
+
+        if (enumValue.getClass().getEnclosingClass() == InteGraalKeywords.Algorithms.Parameters.Compilation.class
+                && !usesRuleCompilationAlgorithm()) {
+            throw new IllegalArgumentException(
+                    "Compilation parameter " + enumValue + " cannot be set for " + getAlgorithm() + " algorithms.");
+        }
+
+        if (enumValue.getClass().getEnclosingClass() == InteGraalKeywords.InternalStorageConfiguration.class
+                && !usesStorage()) {
+            throw new IllegalArgumentException(
+                    "Storage parameter " + enumValue + " cannot be set for " + getAlgorithm() + " algorithms.");
+        }
+    }
+
+    private void initDefaultValues() {
+
+        this.answers = Answers.SET;
+
+        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;
+    }
+
 }
diff --git a/integraal/integraal-component/src/main/java/fr/boreal/component_builder/api/algorithm/IExplanationParameters.java b/integraal/integraal-component/src/main/java/fr/boreal/component_builder/api/algorithm/IExplanationParameters.java
index a7357725650947025963ec59a0ae4fe1684c7b32..ed2e0e0f99c6805cf69957756656da24fc31d279 100644
--- a/integraal/integraal-component/src/main/java/fr/boreal/component_builder/api/algorithm/IExplanationParameters.java
+++ b/integraal/integraal-component/src/main/java/fr/boreal/component_builder/api/algorithm/IExplanationParameters.java
@@ -52,4 +52,20 @@ interface IExplanationParameters {
 
 	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
diff --git a/integraal/integraal-configuration/src/main/java/fr/boreal/configuration/keywords/InteGraalKeywords.java b/integraal/integraal-configuration/src/main/java/fr/boreal/configuration/keywords/InteGraalKeywords.java
index 430866010c1f17a0985168e31c782d328860dd67..7e57edfa643bfb4ee9b2f33e91e964931ede0422 100644
--- a/integraal/integraal-configuration/src/main/java/fr/boreal/configuration/keywords/InteGraalKeywords.java
+++ b/integraal/integraal-configuration/src/main/java/fr/boreal/configuration/keywords/InteGraalKeywords.java
@@ -94,8 +94,9 @@ public enum InteGraalKeywords {
 	EXPLAINER_SOLVER(Algorithms.Parameters.Explanation.ExplainerSolver.class),
     EXPLAINER_GRI_COMPUTATION(Algorithms.Parameters.Explanation.GraphOfRuleInstancesComputation.class),
     EXPLAINER_GRI_TYPE(Algorithms.Parameters.Explanation.GraphOfRuleInstancesType.class),
-	EXPLANATION_SUPPORT_TYPE(Algorithms.Parameters.Explanation.ExplanationSupportType.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  ?
     //		 Comment indiquer les valeurs autorisés d'un paramètre (cf. code ci-après) ?
@@ -609,7 +610,19 @@ public enum InteGraalKeywords {
                      */
                     SMART_GSAT_SOLVER
                 }
-                
+
+                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
diff --git a/integraal/integraal-configuration/src/main/java/fr/boreal/configuration/parameters/IGParameterValueExtractor.java b/integraal/integraal-configuration/src/main/java/fr/boreal/configuration/parameters/IGParameterValueExtractor.java
index 494542eca00e05c9805708f35eeb7d5144c026ac..c2fcb4fcc0e1765de733c69ae3436bfc6e9ec698 100644
--- a/integraal/integraal-configuration/src/main/java/fr/boreal/configuration/parameters/IGParameterValueExtractor.java
+++ b/integraal/integraal-configuration/src/main/java/fr/boreal/configuration/parameters/IGParameterValueExtractor.java
@@ -94,4 +94,8 @@ public class IGParameterValueExtractor {
         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);
+    }
+
 }
diff --git a/integraal/integraal-explanation/src/main/java/fr/boreal/explanation/api/builder/AtomicQueryExplainerBuilder.java b/integraal/integraal-explanation/src/main/java/fr/boreal/explanation/api/builder/AtomicQueryExplainerBuilder.java
index 98b2b1c73c1bb6916da3ef7a74c01f49d36eaf64..daedba2603efe05871f9b2e30db47b3a7dc5f638 100644
--- a/integraal/integraal-explanation/src/main/java/fr/boreal/explanation/api/builder/AtomicQueryExplainerBuilder.java
+++ b/integraal/integraal-explanation/src/main/java/fr/boreal/explanation/api/builder/AtomicQueryExplainerBuilder.java
@@ -49,12 +49,15 @@ public final class AtomicQueryExplainerBuilder {
     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) {
@@ -69,17 +72,20 @@ public final class AtomicQueryExplainerBuilder {
                         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){
+    public void withSolver(Solver solver) {
         Objects.requireNonNull(solver, "cannot use this method with a null solver");
         this.solverInstance = solver;
-        this.externallySetSolver=true;
+        this.externallySetSolver = true;
     }
+
     /**
      * Convenience one‑shot creation
      */
@@ -114,14 +120,30 @@ public final class AtomicQueryExplainerBuilder {
 
     private void buildSolver() {
 
-        if(externallySetSolver){
-           return;
+        if (externallySetSolver) {
+            return;
         }
 
         this.solverInstance = switch (this.solverParam) {
-            case MARCO -> new MARCOGMUSSolver();
+            case MARCO -> {
+                if (this.pathToMARCOExecutable != null) {
+                    yield new MARCOGMUSSolver(this.pathToMARCOExecutable);
+                } else {
+                    yield new MARCOGMUSSolver();
+                }
+            }
             case SAT4J -> new Sat4JSolver();
-            case SMART_GSAT_SOLVER -> new HybridSAT4JMARCOSolver();
+            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();
+                }
+            }
         };
     }
 
diff --git a/integraal/integraal-explanation/src/main/java/fr/boreal/explanation/configuration/PathFinder.java b/integraal/integraal-explanation/src/main/java/fr/boreal/explanation/configuration/PathFinder.java
index 228732ea7b88d264d610d87b39731c9b2640d238..ed6ba002754967366b3628e2093a1722bd49d4cf 100644
--- a/integraal/integraal-explanation/src/main/java/fr/boreal/explanation/configuration/PathFinder.java
+++ b/integraal/integraal-explanation/src/main/java/fr/boreal/explanation/configuration/PathFinder.java
@@ -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));
+    }
 }
diff --git a/integraal/integraal-explanation/src/main/java/fr/boreal/explanation/solving_enumerating/hybrid/HybridSAT4JMARCOSolver.java b/integraal/integraal-explanation/src/main/java/fr/boreal/explanation/solving_enumerating/hybrid/HybridSAT4JMARCOSolver.java
index 8bc6c823970a577d060746868409dc6e086f8dd0..cdea4a815575c5d20d753d629cac7668f027e924 100644
--- a/integraal/integraal-explanation/src/main/java/fr/boreal/explanation/solving_enumerating/hybrid/HybridSAT4JMARCOSolver.java
+++ b/integraal/integraal-explanation/src/main/java/fr/boreal/explanation/solving_enumerating/hybrid/HybridSAT4JMARCOSolver.java
@@ -13,18 +13,28 @@ import java.util.Set;
 
 public class HybridSAT4JMARCOSolver implements Solver {
 
-    private Sat4JSolver sat4JSolver = new Sat4JSolver();
+    private final Sat4JSolver sat4JSolver;
 
-    private MARCOGMUSSolver marcoSolver = new MARCOGMUSSolver();
+    private final MARCOGMUSSolver marcoSolver;
 
     private final int TRESHOLD;
 
     public HybridSAT4JMARCOSolver() {
         this.TRESHOLD = 10;
+        this.sat4JSolver = new Sat4JSolver();
+        this.marcoSolver = new MARCOGMUSSolver();
     }
 
     public HybridSAT4JMARCOSolver(int treshold) {
         this.TRESHOLD = treshold;
+        this.sat4JSolver = new Sat4JSolver();
+        this.marcoSolver = new MARCOGMUSSolver();
+    }
+
+    public HybridSAT4JMARCOSolver(int treshold, String marcoPathToExecutable) {
+        this.TRESHOLD = treshold;
+        this.sat4JSolver = new Sat4JSolver();
+        this.marcoSolver = new MARCOGMUSSolver(marcoPathToExecutable);
     }
 
     public HybridSolvingResultDecoded solveAndDecode(GSATEncodingResult_GRI encoding) {
@@ -49,7 +59,7 @@ public class HybridSAT4JMARCOSolver implements Solver {
 
     public HybridSolvingResult solve(GSATEncodingResult_GRI encoding) {
 
-        if (encoding.clauses().size() > TRESHOLD) {
+        if (encoding.clauses().size() < TRESHOLD) {
 
             List<List<List<Integer>>> sat4JGMUSes = sat4JSolver.enumerateGMUSes(encoding.clauses());
             return new HybridSolvingResult(sat4JGMUSes, sat4JSolver);
diff --git a/integraal/integraal-explanation/src/main/java/fr/boreal/explanation/solving_enumerating/marco/MARCOGMUSSolver.java b/integraal/integraal-explanation/src/main/java/fr/boreal/explanation/solving_enumerating/marco/MARCOGMUSSolver.java
index 22cf23784eaff67105089b93fff7d9104d6929b7..5ce9497c9c3705cabcc5eb4db3599168c47c3b84 100644
--- a/integraal/integraal-explanation/src/main/java/fr/boreal/explanation/solving_enumerating/marco/MARCOGMUSSolver.java
+++ b/integraal/integraal-explanation/src/main/java/fr/boreal/explanation/solving_enumerating/marco/MARCOGMUSSolver.java
@@ -3,8 +3,6 @@ package fr.boreal.explanation.solving_enumerating.marco;
 import com.google.common.collect.BiMap;
 import fr.boreal.explanation.api.solver.Solver;
 import fr.boreal.model.logicalElements.api.Atom;
-import fr.boreal.model.logicalElements.api.Term;
-import no.hasmac.jsonld.uri.Path;
 
 import java.io.*;
 import java.util.HashSet;
@@ -16,17 +14,32 @@ import static fr.boreal.explanation.configuration.PathFinder.ensureFilePath;
 
 public class MARCOGMUSSolver implements Solver {
 
-    private static final MARCOGMUSSolver INSTANCE = new MARCOGMUSSolver();
-
-    public static MARCOGMUSSolver instance() {
-        return INSTANCE;
-    }
+    private final String pathToMARCOExecutable;
 
     String tmpFileName = "gsat.gcnf";
     File gcnfFile = new File(tmpFileName);
 
     int timeout = 0;
 
+    public MARCOGMUSSolver(String pathToMARCOExecutableSetByUser) {
+        this.pathToMARCOExecutable =
+                ensureFilePath(
+                        pathToMARCOExecutableSetByUser,
+                        "integraal-explanation/MARCO-MUS/marco.py",
+                        "MARCO-MUS/marco.py");
+    }
+
+    public MARCOGMUSSolver() {
+        this.pathToMARCOExecutable =
+                ensureFilePath(
+                        "integraal-explanation/MARCO-MUS/marco.py",
+                        "MARCO-MUS/marco.py");
+    }
+
+    public String getPathToMARCOExecutable() {
+        return pathToMARCOExecutable;
+    }
+
     /**
      * This main methods call two methods:
      * 1. writeGCNF: Writing the clauses to temporary gsat.gcnf file
@@ -116,9 +129,9 @@ public class MARCOGMUSSolver implements Solver {
         ProcessBuilder build = new ProcessBuilder().redirectErrorStream(true);
         String command;
         if (timeout == 0)
-            build.command(ensureFilePath("integraal-explanation/MARCO-MUS/marco.py", "MARCO-MUS/marco.py"), "-s", "-v", "-b", "MUSes", gcnfFile.getAbsolutePath());
+            build.command(this.pathToMARCOExecutable, "-s", "-v", "-b", "MUSes", gcnfFile.getAbsolutePath());
         else
-            build.command(ensureFilePath("integraal-explanation/MARCO-MUS/marco.py", "MARCO-MUS/marco.py"), "-a", "-v", "-b", "MUSes", "-T", Long.toString(timeout), gcnfFile.getAbsolutePath());
+            build.command(this.pathToMARCOExecutable, "-a", "-v", "-b", "MUSes", "-T", Long.toString(timeout), gcnfFile.getAbsolutePath());
         Process proc;
         try {
             proc = build.start();