From c0c5a1644cc221352b8b9b370eea6a87677ba948 Mon Sep 17 00:00:00 2001 From: Kristóf Marussy Date: Sat, 15 Jun 2019 20:56:47 -0400 Subject: Try fix statecode bug Modified graph width calculation to not depend on order of nodes --- .../viatrasolver/reasoner/ViatraReasoner.xtend | 9 +- .../reasoner/ViatraReasonerConfiguration.xtend | 3 +- .../dse/BestFirstStrategyForModelGeneration.java | 8 +- .../AbstractThreeValuedObjective.xtend | 71 +-------- .../CompositeDirectionalThresholdObjective.xtend | 62 ++++++++ .../DirectionalThresholdObjective.xtend | 164 +++++++++++++++++++++ .../reasoner/optimization/MatchCostObjective.xtend | 52 +++++++ .../reasoner/optimization/ObjectiveKind.java | 24 +++ .../optimization/QueryBasedObjective.xtend | 48 ++++++ .../optimization/ThreeValuedCostObjective.xtend | 2 +- 10 files changed, 365 insertions(+), 78 deletions(-) create mode 100644 Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/optimization/CompositeDirectionalThresholdObjective.xtend create mode 100644 Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/optimization/DirectionalThresholdObjective.xtend create mode 100644 Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/optimization/MatchCostObjective.xtend create mode 100644 Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/optimization/QueryBasedObjective.xtend (limited to 'Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src') diff --git a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/ViatraReasoner.xtend b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/ViatraReasoner.xtend index edcca676..701eb054 100644 --- a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/ViatraReasoner.xtend +++ b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/ViatraReasoner.xtend @@ -16,8 +16,9 @@ import hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.ScopePropagator import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.PartialInterpretationInitialiser import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PartialInterpretation import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PartialinterpretationPackage +import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.statecoder.AbstractNeighbourhoodBasedStateCoderFactory import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.statecoder.IdentifierBasedStateCoderFactory -import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.statecoder.NeighbourhoodBasedStateCoderFactory +import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.statecoder.PairwiseNeighbourhoodBasedStateCoderFactory import hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.dse.BestFirstStrategyForModelGeneration import hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.dse.DiversityChecker import hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.dse.LoggerSolutionFoundHandler @@ -49,7 +50,7 @@ class ViatraReasoner extends LogicReasoner { ReasonerWorkspace workspace) throws LogicReasonerException { val viatraConfig = configuration.asConfig - if (viatraConfig.debugConfiguration.logging) { + if (viatraConfig.documentationLevel == DocumentationLevel.FULL) { DesignSpaceExplorer.turnOnLogging(DseLoggingLevel.VERBOSE_FULL) } else { DesignSpaceExplorer.turnOnLogging(DseLoggingLevel.WARN) @@ -139,7 +140,7 @@ class ViatraReasoner extends LogicReasoner { dse.setInitialModel(emptySolution, false) val IStateCoderFactory statecoder = if (viatraConfig.stateCoderStrategy == StateCoderStrategy.Neighbourhood) { - new NeighbourhoodBasedStateCoderFactory + new PairwiseNeighbourhoodBasedStateCoderFactory } else { new IdentifierBasedStateCoderFactory } @@ -239,7 +240,7 @@ class ViatraReasoner extends LogicReasoner { } } - private def dispatch long runtime(NeighbourhoodBasedStateCoderFactory sc) { + private def dispatch long runtime(AbstractNeighbourhoodBasedStateCoderFactory sc) { sc.sumStatecoderRuntime } diff --git a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/ViatraReasonerConfiguration.xtend b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/ViatraReasonerConfiguration.xtend index e6aee20c..99decdd9 100644 --- a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/ViatraReasonerConfiguration.xtend +++ b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/ViatraReasonerConfiguration.xtend @@ -64,8 +64,7 @@ class DiversityDescriptor { } class DebugConfiguration { - public var logging = false - public var PartialInterpretationVisualiser partialInterpretatioVisualiser = null; + public var PartialInterpretationVisualiser partialInterpretatioVisualiser = null public var partalInterpretationVisualisationFrequency = 1 } diff --git a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/BestFirstStrategyForModelGeneration.java b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/BestFirstStrategyForModelGeneration.java index 077fea21..144e7484 100644 --- a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/BestFirstStrategyForModelGeneration.java +++ b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/BestFirstStrategyForModelGeneration.java @@ -20,8 +20,8 @@ import java.util.List; import java.util.PriorityQueue; import java.util.Random; -import org.apache.log4j.Level; import org.apache.log4j.Logger; +import org.eclipse.emf.ecore.EObject; import org.eclipse.emf.ecore.util.EcoreUtil; import org.eclipse.viatra.dse.api.strategy.interfaces.IStrategy; import org.eclipse.viatra.dse.base.ThreadContext; @@ -254,6 +254,7 @@ public class BestFirstStrategyForModelGeneration implements IStrategy { activationIds = new ArrayList(context.getUntraversedActivationIds()); Collections.shuffle(activationIds); } catch (NullPointerException e) { + logger.warn("Unexpected state code: " + context.getDesignSpaceManager().getCurrentState()); numberOfStatecoderFail++; activationIds = Collections.emptyList(); } @@ -295,7 +296,10 @@ public class BestFirstStrategyForModelGeneration implements IStrategy { int id = ++numberOfPrintedModel; if (id % configuration.debugConfiguration.partalInterpretationVisualisationFrequency == 0) { PartialInterpretationVisualisation visualisation = partialInterpretatioVisualiser.visualiseConcretization(p); - visualisation.writeToFile(workspace, String.format("state%09d.png", id)); + logger.debug("Visualizing state: " + id + " (" + context.getDesignSpaceManager().getCurrentState() + ")"); + String name = String.format("state%09d", id); + visualisation.writeToFile(workspace, name + ".png"); + workspace.writeModel((EObject) context.getModel(), name + ".xmi"); } } } diff --git a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/optimization/AbstractThreeValuedObjective.xtend b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/optimization/AbstractThreeValuedObjective.xtend index 241bef2a..cd911ab5 100644 --- a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/optimization/AbstractThreeValuedObjective.xtend +++ b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/optimization/AbstractThreeValuedObjective.xtend @@ -1,60 +1,10 @@ package hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.optimization -import java.util.Comparator import org.eclipse.viatra.dse.base.ThreadContext -import org.eclipse.xtend.lib.annotations.Accessors -import org.eclipse.xtend.lib.annotations.Data - -abstract class ObjectiveThreshold { - public static val NO_THRESHOLD = new hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.optimization.ObjectiveThreshold { - override isHard() { - false - } - - override satisfiesThreshold(double cost, Comparator comparator) { - true - } - } - - private new() { - } - - def boolean isHard() { - true - } - - def boolean satisfiesThreshold(double cost, Comparator comparator) - - @Data - static class Exclusive extends ObjectiveThreshold { - val double threshold - - override satisfiesThreshold(double cost, Comparator comparator) { - comparator.compare(threshold, cost) > 0 - } - } - - @Data - static class Inclusive extends ObjectiveThreshold { - val double threshold - - override satisfiesThreshold(double cost, Comparator comparator) { - comparator.compare(threshold, cost) >= 0 - } - } -} - -abstract class AbstractThreeValuedObjective implements IThreeValuedObjective { - @Accessors val String name - @Accessors ObjectiveKind kind - @Accessors ObjectiveThreshold threshold - @Accessors int level +abstract class AbstractThreeValuedObjective extends DirectionalThresholdObjective implements IThreeValuedObjective { protected new(String name, ObjectiveKind kind, ObjectiveThreshold threshold, int level) { - this.name = name - this.kind = kind - this.threshold = threshold - this.level = level + super(name, kind, threshold, level) } abstract def double getLowestPossibleFitness(ThreadContext threadContext) @@ -82,21 +32,4 @@ abstract class AbstractThreeValuedObjective implements IThreeValuedObjective { throw new IllegalStateException("Unknown three valued objective kind: " + kind) } } - - override isHardObjective() { - threshold.hard - } - - override satisifiesHardObjective(Double fitness) { - threshold.satisfiesThreshold(fitness, comparator) - } - - override getComparator() { - kind.comparator - } - - override setComparator(Comparator comparator) { - kind = ObjectiveKind.fromComparator(comparator) - } - } diff --git a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/optimization/CompositeDirectionalThresholdObjective.xtend b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/optimization/CompositeDirectionalThresholdObjective.xtend new file mode 100644 index 00000000..0aa442f5 --- /dev/null +++ b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/optimization/CompositeDirectionalThresholdObjective.xtend @@ -0,0 +1,62 @@ +package hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.optimization + +import com.google.common.collect.ImmutableList +import java.util.Collection +import org.eclipse.viatra.dse.base.ThreadContext + +class CompositeDirectionalThresholdObjective extends DirectionalThresholdObjective { + val Collection objectives + + new(String name, Collection objectives) { + this(name, objectives, getKind(objectives), getThreshold(objectives), getLevel(objectives)) + } + + new(String name, DirectionalThresholdObjective... objectives) { + this(name, objectives as Collection) + } + + protected new(String name, Iterable objectives, ObjectiveKind kind, + ObjectiveThreshold threshold, int level) { + super(name, kind, threshold, level) + this.objectives = ImmutableList.copyOf(objectives) + } + + override createNew() { + new CompositeDirectionalThresholdObjective(name, objectives.map[createNew as DirectionalThresholdObjective], + kind, threshold, level) + } + + override init(ThreadContext context) { + for (objective : objectives) { + objective.init(context) + } + } + + override protected getRawFitness(ThreadContext context) { + var double fitness = 0 + for (objective : objectives) { + fitness += objective.getFitness(context) + } + fitness + } + + private static def getKind(Collection objectives) { + val kinds = objectives.map[kind].toSet + if (kinds.size != 1) { + throw new IllegalArgumentException("Passed objectives must have the same kind") + } + kinds.head + } + + private static def getThreshold(Collection objectives) { + objectives.map[threshold].reduce[a, b|a.merge(b)] + } + + private static def int getLevel(Collection objectives) { + val levels = objectives.map[level].toSet + if (levels.size != 1) { + throw new IllegalArgumentException("Passed objectives must have the same level") + } + levels.head + } +} diff --git a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/optimization/DirectionalThresholdObjective.xtend b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/optimization/DirectionalThresholdObjective.xtend new file mode 100644 index 00000000..376e3d1a --- /dev/null +++ b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/optimization/DirectionalThresholdObjective.xtend @@ -0,0 +1,164 @@ +package hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.optimization + +import java.util.Comparator +import org.eclipse.viatra.dse.base.ThreadContext +import org.eclipse.viatra.dse.objectives.IObjective +import org.eclipse.xtend.lib.annotations.Accessors +import org.eclipse.xtend.lib.annotations.Data +import org.eclipse.xtend.lib.annotations.FinalFieldsConstructor + +abstract class ObjectiveThreshold { + public static val NO_THRESHOLD = new ObjectiveThreshold { + override isHard() { + false + } + + override satisfiesThreshold(double cost, Comparator comparator) { + true + } + + override protected postProcessSatisfactoryCost(double cost, ObjectiveKind kind) { + cost + } + + override ObjectiveThreshold merge(ObjectiveThreshold other) { + if (other == NO_THRESHOLD) { + NO_THRESHOLD + } else { + throw new IllegalArgumentException("Merged thresholds must have the same type") + } + } + } + + private new() { + } + + def boolean isHard() { + true + } + + def boolean satisfiesThreshold(double cost, ObjectiveKind kind) { + satisfiesThreshold(cost, kind.comparator) + } + + def boolean satisfiesThreshold(double cost, Comparator comparator) + + def double postProcessCost(double cost, ObjectiveKind kind) { + if (satisfiesThreshold(cost, kind)) { + postProcessSatisfactoryCost(cost, kind) + } else { + cost + } + } + + protected def double postProcessSatisfactoryCost(double cost, ObjectiveKind kind) + + def ObjectiveThreshold merge(ObjectiveThreshold other) + + @Data + static class Exclusive extends ObjectiveThreshold { + static val EPSILON = 0.1 + + val double threshold + val boolean clampToThreshold + + @FinalFieldsConstructor + new() { + } + + new(double threshold) { + this(threshold, true) + } + + override satisfiesThreshold(double cost, Comparator comparator) { + comparator.compare(threshold, cost) < 0 + } + + override protected postProcessSatisfactoryCost(double cost, ObjectiveKind kind) { + if (clampToThreshold) { + threshold + Math.signum(kind.satisfiedValue) * EPSILON + } else { + cost + } + } + + override ObjectiveThreshold merge(ObjectiveThreshold other) { + if (other instanceof Exclusive) { + new Exclusive(threshold + other.threshold) + } else { + throw new IllegalArgumentException("Merged thresholds must have the same type") + } + } + } + + @Data + static class Inclusive extends ObjectiveThreshold { + val double threshold + val boolean clampToThreshold + + @FinalFieldsConstructor + new() { + } + + new(double threshold) { + this(threshold, true) + } + + override satisfiesThreshold(double cost, Comparator comparator) { + comparator.compare(threshold, cost) <= 0 + } + + override protected postProcessSatisfactoryCost(double cost, ObjectiveKind kind) { + if (clampToThreshold) { + threshold + } else { + cost + } + } + + override ObjectiveThreshold merge(ObjectiveThreshold other) { + if (other instanceof Inclusive) { + new Inclusive(threshold + other.threshold) + } else { + throw new IllegalArgumentException("Merged thresholds must have the same type") + } + } + } +} + +abstract class DirectionalThresholdObjective implements IObjective { + @Accessors val String name + @Accessors ObjectiveKind kind + @Accessors ObjectiveThreshold threshold + @Accessors int level + + protected new(String name, ObjectiveKind kind, ObjectiveThreshold threshold, int level) { + this.name = name + this.kind = kind + this.threshold = threshold + this.level = level + } + + override isHardObjective() { + threshold.hard + } + + override satisifiesHardObjective(Double fitness) { + threshold.satisfiesThreshold(fitness, comparator) + } + + override getComparator() { + kind.comparator + } + + override setComparator(Comparator comparator) { + kind = ObjectiveKind.fromComparator(comparator) + } + + override getFitness(ThreadContext context) { + val fitness = getRawFitness(context) + threshold.postProcessCost(fitness, kind) + } + + protected def double getRawFitness(ThreadContext context) +} diff --git a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/optimization/MatchCostObjective.xtend b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/optimization/MatchCostObjective.xtend new file mode 100644 index 00000000..a0c6a2c1 --- /dev/null +++ b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/optimization/MatchCostObjective.xtend @@ -0,0 +1,52 @@ +package hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.optimization + +import com.google.common.collect.ImmutableList +import java.util.Collection +import org.eclipse.viatra.dse.base.ThreadContext +import org.eclipse.viatra.query.runtime.api.IPatternMatch +import org.eclipse.viatra.query.runtime.api.IQuerySpecification +import org.eclipse.viatra.query.runtime.api.ViatraQueryMatcher +import org.eclipse.xtend.lib.annotations.Data + +@Data +class MatchCostElement { + val IQuerySpecification> querySpecification + val double weight +} + +class MatchCostObjective extends DirectionalThresholdObjective { + val Collection costElements + Collection matchers + + new(String name, Collection costElements, ObjectiveKind kind, ObjectiveThreshold threshold, + int level) { + super(name, kind, threshold, level) + this.costElements = costElements + } + + override createNew() { + new MatchCostObjective(name, costElements, kind, threshold, level) + } + + override init(ThreadContext context) { + val queryEngine = context.queryEngine + matchers = ImmutableList.copyOf(costElements.map [ + val matcher = querySpecification.getMatcher(queryEngine) + new CostElementMatcher(matcher, weight) + ]) + } + + override protected getRawFitness(ThreadContext context) { + var double cost = 0 + for (it : matchers) { + cost += weight * matcher.countMatches + } + cost + } + + @Data + private static class CostElementMatcher { + val ViatraQueryMatcher matcher + val double weight + } +} diff --git a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/optimization/ObjectiveKind.java b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/optimization/ObjectiveKind.java index f65428fe..cbbaaafd 100644 --- a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/optimization/ObjectiveKind.java +++ b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/optimization/ObjectiveKind.java @@ -12,6 +12,16 @@ public enum ObjectiveKind { return Comparators.LOWER_IS_BETTER; } + @Override + public double getInvalidValue() { + return Double.POSITIVE_INFINITY; + } + + @Override + public double getSatisfiedValue() { + return Double.NEGATIVE_INFINITY; + } + }, HIGHER_IS_BETTER { @@ -20,10 +30,24 @@ public enum ObjectiveKind { return Comparators.HIGHER_IS_BETTER; } + @Override + public double getInvalidValue() { + return Double.NEGATIVE_INFINITY; + } + + @Override + public double getSatisfiedValue() { + return Double.POSITIVE_INFINITY; + } + }; public abstract Comparator getComparator(); + public abstract double getInvalidValue(); + + public abstract double getSatisfiedValue(); + public static ObjectiveKind fromComparator(Comparator comparator) { if (Comparators.LOWER_IS_BETTER.equals(comparator)) { return ObjectiveKind.LOWER_IS_BETTER; diff --git a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/optimization/QueryBasedObjective.xtend b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/optimization/QueryBasedObjective.xtend new file mode 100644 index 00000000..d355f5be --- /dev/null +++ b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/optimization/QueryBasedObjective.xtend @@ -0,0 +1,48 @@ +package hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.optimization + +import org.eclipse.viatra.dse.base.ThreadContext +import org.eclipse.viatra.query.runtime.api.IPatternMatch +import org.eclipse.viatra.query.runtime.api.IQuerySpecification +import org.eclipse.viatra.query.runtime.api.ViatraQueryMatcher + +class QueryBasedObjective extends DirectionalThresholdObjective { + val IQuerySpecification> querySpecification + ViatraQueryMatcher matcher + + new(IQuerySpecification> querySpecification, + ObjectiveKind kind, ObjectiveThreshold threshold, int level) { + super(querySpecification.simpleName + " objective", kind, threshold, level) + if (querySpecification.parameters.size != 1) { + throw new IllegalArgumentException("Objective query must have a single parameter") + } + this.querySpecification = querySpecification + } + + override createNew() { + new QueryBasedObjective(querySpecification, kind, threshold, level) + } + + override init(ThreadContext context) { + matcher = querySpecification.getMatcher(context.queryEngine) + } + + override protected getRawFitness(ThreadContext context) { + val iterator = matcher.allMatches.iterator + if (!iterator.hasNext) { + return invalidValue + } + val value = iterator.next.get(0) + if (iterator.hasNext) { + throw new IllegalStateException("Multiple matches for objective query") + } + if (value instanceof Number) { + value.doubleValue + } else { + throw new IllegalStateException("Objective value is not an instance of Number") + } + } + + private def getInvalidValue() { + kind.invalidValue + } +} diff --git a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/optimization/ThreeValuedCostObjective.xtend b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/optimization/ThreeValuedCostObjective.xtend index e2585c83..0a6fd55b 100644 --- a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/optimization/ThreeValuedCostObjective.xtend +++ b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/optimization/ThreeValuedCostObjective.xtend @@ -42,7 +42,7 @@ class ThreeValuedCostObjective extends AbstractThreeValuedObjective { ]) } - override getFitness(ThreadContext context) { + override getRawFitness(ThreadContext context) { var int cost = 0 for (matcher : matchers) { cost += matcher.weight * matcher.currentMatcher.countMatches -- cgit v1.2.3-54-g00ecf