/*******************************************************************************
* Copyright (c) 2010-2017, Andras Szabolcs Nagy and Daniel Varro
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
* Contributors:
* Andras Szabolcs Nagy - initial API and implementation
*******************************************************************************/
package hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.dse;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.PriorityQueue;
import java.util.Random;
import java.util.SortedMap;
import java.util.TreeMap;
import java.util.TreeSet;
import org.apache.log4j.Logger;
import org.eclipse.viatra.dse.api.strategy.interfaces.IStrategy;
import org.eclipse.viatra.dse.base.ThreadContext;
import org.eclipse.viatra.dse.objectives.Fitness;
import org.eclipse.viatra.dse.objectives.ObjectiveComparatorHelper;
import org.eclipse.viatra.dse.solutionstore.SolutionStore;
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.viatra.query.runtime.exception.ViatraQueryException;
import hu.bme.mit.inf.dslreasoner.logic.model.builder.LogicReasoner;
import hu.bme.mit.inf.dslreasoner.logic.model.builder.LogicSolverConfiguration;
import hu.bme.mit.inf.dslreasoner.logic.model.logicresult.ModelResult;
import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretation2logic.PartialInterpretation2Logic;
import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PartialInterpretation;
import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.visualisation.PartialInterpretation2Gml;
import hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.DiversityDescriptor;
import hu.bme.mit.inf.dslreasoner.workspace.ReasonerWorkspace;
/**
* This exploration strategy eventually explorers the whole design space but goes in the most promising directions
* first, based on the {@link Fitness}.
*
* There are a few parameter to tune such as
*
*
maximum depth
*
continue the exploration from a state that satisfies the hard objectives (the default that it will
* backtrack),
*
whether to continue the exploration from the newly explored state if it is at least equally good than the
* previous one or only if it is better (default is "at least equally good").
*
*
* @author Andras Szabolcs Nagy
*
*/
public class BestFirstStrategyForModelGeneration implements IStrategy {
private ThreadContext context;
private SolutionStore solutionStore;
private SolutionStoreWithCopy solutionStoreWithCopy;
private SolutionStoreWithDiversityDescriptor solutionStoreWithDiversityDescriptor;
private int numberOfStatecoderFail=0;
//Collection extends IQuerySpecification extends ViatraQueryMatcher extends IPatternMatch>>> additionalPatterns = null;
//List> additionalMatchers = new LinkedList>();
private int maxDepth = Integer.MAX_VALUE;
private boolean isInterrupted = false;
//private boolean backTrackIfSolution = true;
private boolean onlyBetterFirst = false;
private PriorityQueue trajectoiresToExplore;
private Logger logger = Logger.getLogger(IStrategy.class);
private static class TrajectoryWithFitness {
public Object[] trajectory;
public Fitness fitness;
public TrajectoryWithFitness(Object[] trajectory, Fitness fitness) {
super();
this.trajectory = trajectory;
this.fitness = fitness;
}
@Override
public String toString() {
return Arrays.toString(trajectory) + fitness.toString();
}
}
public BestFirstStrategyForModelGeneration(
ReasonerWorkspace workspace, LogicReasoner reasoner, LogicSolverConfiguration configuration, DiversityDescriptor descriptor/*,
Collection extends IQuerySpecification extends ViatraQueryMatcher extends IPatternMatch>>> additionalPatterns*/) {
this.maxDepth = Integer.MAX_VALUE;
this.workspace = workspace;
this.reasoner = reasoner;
this.configuration = configuration;
this.solutionStoreWithDiversityDescriptor = new SolutionStoreWithDiversityDescriptor(descriptor);
//this.additionalPatterns = additionalPatterns;
}
@Override
public void initStrategy(ThreadContext context) {
this.context = context;
this.solutionStore = context.getGlobalContext().getSolutionStore();
this.solutionStoreWithCopy = new SolutionStoreWithCopy();
final ObjectiveComparatorHelper objectiveComparatorHelper = context.getObjectiveComparatorHelper();
Comparator comparator = new Comparator() {
@Override
public int compare(TrajectoryWithFitness o1, TrajectoryWithFitness o2) {
return objectiveComparatorHelper.compare(o2.fitness, o1.fitness);
}
};
trajectoiresToExplore = new PriorityQueue(11, comparator);
}
public SolutionStoreWithCopy getSolutionStoreWithCopy() {
return solutionStoreWithCopy;
}
public SolutionStoreWithDiversityDescriptor getSolutionStoreWithDiversityDescriptor() {
return solutionStoreWithDiversityDescriptor;
}
public int getNumberOfStatecoderFaiL() {
return numberOfStatecoderFail;
}
@Override
public void explore() {
/*if(this.additionalPatterns!=null) {
for (IQuerySpecification extends ViatraQueryMatcher extends IPatternMatch>> additionalPattern : additionalPatterns) {
try {
this.additionalMatchers.add(additionalPattern.getMatcher(context.getQueryEngine()));
} catch (ViatraQueryException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}*/
final ObjectiveComparatorHelper objectiveComparatorHelper = context.getObjectiveComparatorHelper();
boolean globalConstraintsAreSatisfied = context.checkGlobalConstraints();
if (!globalConstraintsAreSatisfied) {
logger.info("Global contraint is not satisifed in the first state. Terminate.");
return;
}
final Fitness firstFittness = context.calculateFitness();
if (firstFittness.isSatisifiesHardObjectives()) {
context.newSolution();
logger.info("First state is a solution. Terminate.");
return;
}
if (maxDepth == 0) {
return;
}
final Object[] firstTrajectory = context.getTrajectory().toArray(new Object[0]);
TrajectoryWithFitness currentTrajectoryWithFittness = new TrajectoryWithFitness(firstTrajectory, firstFittness);
trajectoiresToExplore.add(currentTrajectoryWithFittness);
mainLoop: while (!isInterrupted) {
if (currentTrajectoryWithFittness == null) {
if (trajectoiresToExplore.isEmpty()) {
logger.debug("State space is fully traversed.");
return;
} else {
currentTrajectoryWithFittness = selectRandomState();// trajectoiresToExplore.element();
if (logger.isDebugEnabled()) {
logger.debug("Current trajectory: " + Arrays.toString(context.getTrajectory().toArray()));
logger.debug("New trajectory is chosen: " + currentTrajectoryWithFittness);
}
// context.backtrackUntilRoot();
// context.executeTrajectoryWithoutStateCoding(currentTrajectoryWithFittness.trajectory);
context.getDesignSpaceManager().executeTrajectoryWithMinimalBacktrackWithoutStateCoding(currentTrajectoryWithFittness.trajectory);
}
}
List