From 3047e5810f0fd80c0d9c7e326360790e23e0cda2 Mon Sep 17 00:00:00 2001 From: MarkBeB <177214717+MarkBeB@users.noreply.github.com> Date: Thu, 13 Aug 2026 13:15:44 +0200 Subject: [PATCH 1/2] Rename buildProblemTimed to buildProblem - Timed new default - Also add observer for tracing --- .../src/org/emoflon/gips/core/GipsEngine.java | 104 ++++++------------ 1 file changed, 31 insertions(+), 73 deletions(-) diff --git a/org.emoflon.gips.core/src/org/emoflon/gips/core/GipsEngine.java b/org.emoflon.gips.core/src/org/emoflon/gips/core/GipsEngine.java index d350b456..daac7986 100644 --- a/org.emoflon.gips.core/src/org/emoflon/gips/core/GipsEngine.java +++ b/org.emoflon.gips.core/src/org/emoflon/gips/core/GipsEngine.java @@ -74,8 +74,8 @@ public abstract class GipsEngine { * Builds the problem with time measurement included. This method does not * trigger an update of the pattern matcher and runs everything sequentially. */ - public void buildProblemTimed() { - buildProblemTimed(false, false); + public void buildProblem() { + buildProblem(false, false); } /** @@ -86,8 +86,8 @@ public void buildProblemTimed() { * @param doUpdate If true, the pattern matcher will be updated before building * the problem. */ - public void buildProblemTimed(final boolean doUpdate) { - buildProblemTimed(doUpdate, false); + public void buildProblem(final boolean doUpdate) { + buildProblem(doUpdate, false); } /** @@ -99,7 +99,7 @@ public void buildProblemTimed(final boolean doUpdate) { * the problem. * @param parallel If true, the problem will be built in parallel. */ - public void buildProblemTimed(final boolean doUpdate, final boolean parallel) { + public void buildProblem(final boolean doUpdate, final boolean parallel) { final Observer observer = Observer.getInstance(); observer.observe("BUILD", () -> { if (doUpdate) @@ -116,6 +116,11 @@ public void buildProblemTimed(final boolean doUpdate, final boolean parallel) { // Reset trace getTracer().resetTrace(); + // Objectives will be build by the global objective call below +// objectives.values().parallelStream().forEach(objective -> objective.clear()); + // TODO: It seems to me that this is not necessary for objectives. All tests + // (and also the dedicated tests for checking this!) are happy with it. + nonMappingVariables.clear(); StreamUtils.toStream(mappers.values(), parallel) // .flatMap(mapper -> StreamUtils.toStream(mapper.getMappings().values(), parallel)) // @@ -157,96 +162,49 @@ public void buildProblemTimed(final boolean doUpdate, final boolean parallel) { solver.buildMILPProblem(); }); - buildTraceGraphAndSendToIDE(); + observer.observe("BUILD_TRACE", () -> { + buildTraceGraphAndSendToIDE(); + }); }); } /** - * Builds the problem with no time measurement included. This method does not - * trigger an update of the pattern matcher and runs everything sequentially. + * Builds the problem. This method does not trigger an update of the pattern + * matcher and runs everything sequentially. + * + * @deprecated use {@link #buildProblem()} */ - public void buildProblem() { + @Deprecated + public void buildProblemTimed() { buildProblem(false, false); } /** - * Builds the problem with time no measurement included. This method does - * trigger an update of the pattern matcher depending on the given input - * parameter and runs everything sequentially. + * Builds the problem. This method does trigger an update of the pattern matcher + * depending on the given input parameter and runs everything sequentially. * * @param doUpdate If true, the pattern matcher will be updated before building * the problem. + * @deprecated use {@link #buildProblem(boolean)} */ - public void buildProblem(final boolean doUpdate) { + @Deprecated + public void buildProblemTimed(final boolean doUpdate) { buildProblem(doUpdate, false); } /** - * Builds the problem with no time measurement included. `doUpdate` defines if - * the pattern matcher should be updated and `parallel` decides if the method - * runs everything in parallel or sequentially. + * Builds the problem. `doUpdate` defines if the pattern matcher should be + * updated and `parallel` decides if the method runs everything in parallel or + * sequentially. * * @param doUpdate If true, the pattern matcher will be updated before building * the problem. * @param parallel If true, the problem will be built in parallel. + * @deprecated use {@link #buildProblem(boolean, boolean)} */ - public void buildProblem(final boolean doUpdate, final boolean parallel) { - if (doUpdate) - update(); - - // Reset validation log - validationLog = new GipsConstraintValidationLog(); - - // Constraints are re-build a few lines below - StreamUtils.toStream(constraints.values(), parallel).forEach(constraint -> constraint.clear()); - StreamUtils.toStream(typeExtensions.values(), parallel).forEach(typeExtension -> typeExtension.clear()); - - // Reset trace - getTracer().resetTrace(); - - // Objectives will be build by the global objective call below -// objectives.values().parallelStream().forEach(objective -> objective.clear()); - // TODO: It seems to me that this is not necessary for objectives. All tests - // (and also the dedicated tests for checking this!) are happy with it. - - nonMappingVariables.clear(); - StreamUtils.toStream(mappers.values(), parallel) // - .flatMap(mapper -> StreamUtils.toStream(mapper.getMappings().values(), parallel)) // - .filter(m -> m.hasAdditionalVariables()) // - .forEach(m -> { - Map> variables = nonMappingVariables.get(m); - if (variables == null) { - variables = Collections.synchronizedMap(new HashMap<>()); - nonMappingVariables.put(m, variables); - } - variables.putAll(m.getAdditionalVariables()); - }); - - StreamUtils.toStream(constraints.values(), parallel) - .forEach(constraint -> constraint.calcAdditionalVariables()); - StreamUtils.toStream(typeExtensions.values(), parallel) - .forEach(typeExtension -> typeExtension.calculateExtensions()); - - updateConstants(); - - StreamUtils.toStream(constraints.values(), parallel) - .forEach(constraint -> constraint.buildConstraints(parallel)); - - // Check if GIPS is configure to remove duplicate constraints - if (this.config.removeUselessConstraints()) { - this.removedConstraintsStats = removeUselessConstraints(config.printUselessConstraintsStats()); - } - - if (objective != null) - objective.buildObjectiveFunction(parallel); - - // Sanity check for all variable names: there must not be two different - // variables with the same name. - checkVariableNameSanity(); - - solver.init(); - solver.buildMILPProblem(); - buildTraceGraphAndSendToIDE(); + @Deprecated + public void buildProblemTimed(final boolean doUpdate, final boolean parallel) { + buildProblem(doUpdate, parallel); } /** From bce418099de7339cfb018ce6be35f1b0dbc8936d Mon Sep 17 00:00:00 2001 From: MarkBeB <177214717+MarkBeB@users.noreply.github.com> Date: Thu, 13 Aug 2026 15:11:36 +0200 Subject: [PATCH 2/2] Renamed solveProblemTimed to solveProblem - Timed is new default --- .../src/org/emoflon/gips/core/GipsEngine.java | 56 ++++++++++--------- 1 file changed, 31 insertions(+), 25 deletions(-) diff --git a/org.emoflon.gips.core/src/org/emoflon/gips/core/GipsEngine.java b/org.emoflon.gips.core/src/org/emoflon/gips/core/GipsEngine.java index daac7986..242dea6d 100644 --- a/org.emoflon.gips.core/src/org/emoflon/gips/core/GipsEngine.java +++ b/org.emoflon.gips.core/src/org/emoflon/gips/core/GipsEngine.java @@ -8,7 +8,6 @@ import java.util.Locale; import java.util.Map; import java.util.Objects; -import java.util.function.Supplier; import org.emoflon.gips.core.GipsConstraint.RemovedConstraintsStats; import org.emoflon.gips.core.milp.ConstraintSorter; @@ -263,37 +262,44 @@ protected void buildTraceGraphAndSendToIDE() { } } + /** + * + * @return + * @deprecated use {@link #solveProblem()} + */ public SolverOutput solveProblemTimed() { - Observer observer = Observer.getInstance(); - SolverOutput out = observer.observe("SOLVE_PROBLEM", (Supplier) this::solveProblem); - return out; + return solveProblem(); } public SolverOutput solveProblem() { - SolverOutput output; - if (validationLog.isNotValid()) { - output = new SolverOutput(SolverStatus.INFEASIBLE, Double.NaN, validationLog, 0, null); - } else { - this.tockInit(); - output = solver.solve(); - - if (output.status() != SolverStatus.INFEASIBLE && output.solutionCount() > 0) - solver.updateValuesFromSolution(); + Observer observer = Observer.getInstance(); + return observer.observe("SOLVE_PROBLEM", () -> { + SolverOutput output; + if (validationLog.isNotValid()) { + output = new SolverOutput(SolverStatus.INFEASIBLE, Double.NaN, validationLog, 0, null); + } else { + this.tockInit(); + output = solver.solve(); + + if (output.status() != SolverStatus.INFEASIBLE && output.solutionCount() > 0) + solver.updateValuesFromSolution(); + + if (output.status() == SolverStatus.INFEASIBLE && solver.getSolverConfig().isEnableIIS()) + solver.computeIrreducibleInconsistentSubsystem(); + } - if (output.status() == SolverStatus.INFEASIBLE && solver.getSolverConfig().isEnableIIS()) - solver.computeIrreducibleInconsistentSubsystem(); - } + // Set statistics values of the removed constraints + if (this.removedConstraintsStats != null && output.stats() != null) { + output.stats().setRemovedDuplicateConstraints(this.removedConstraintsStats.duplicates()); + output.stats().setRemovedTrivialConstraints(this.removedConstraintsStats.trivial()); + } - // Set statistics values of the removed constraints - if (this.removedConstraintsStats != null && output.stats() != null) { - output.stats().setRemovedDuplicateConstraints(this.removedConstraintsStats.duplicates()); - output.stats().setRemovedTrivialConstraints(this.removedConstraintsStats.trivial()); - } + solver.reset(); + GlobalMappingIndexer.getInstance().terminate(); - solver.reset(); - GlobalMappingIndexer.getInstance().terminate(); - eclipseIntegration.sendSolutionValuesToIDE(); - return output; + observer.observe("TRACE_VALUES", () -> eclipseIntegration.sendSolutionValuesToIDE()); + return output; + }); } public GipsMapper getMapper(final String mappingName) {