package org.aksw.combinatorics.algos; import java.util.function.BinaryOperator; import java.util.function.Predicate; import java.util.stream.Stream; import org.aksw.combinatorics.solvers.Problem; import org.aksw.isomorphism.ActionProblemContainer; import org.aksw.isomorphism.ProblemContainer; import org.aksw.isomorphism.ProblemContainerPick; import org.aksw.state_space_search.core.Action; import org.aksw.state_space_search.core.State; /** * Class that wraps a {@link Problem} with the {@link State} interface. * * @author raven * * @param <S> */ public class StateProblemContainer<S> implements State<S> { protected ProblemContainer<S> problemContainer; protected Predicate<S> isUnsolveable; protected S baseSolution; protected BinaryOperator<S> solutionCombiner; public StateProblemContainer(S baseSolution, Predicate<S> isUnsolveable, ProblemContainer<S> problemContainer, BinaryOperator<S> solutionCombiner) { super(); this.baseSolution = baseSolution; this.problemContainer = problemContainer; this.solutionCombiner = solutionCombiner; } @Override public boolean isFinal() { boolean result = problemContainer.isEmpty() || isUnsolveable.test(baseSolution); return result; } @Override public S getSolution() { return baseSolution; } /** * Actions are created by means of first solving the cheapest open problem * generating an action for each obtained solution. * (assumes a non-final state) * * */ @Override public Stream<Action<S>> getActions() { ProblemContainerPick<S> pick = problemContainer.pick(); Problem<S> picked = pick.getPicked(); ProblemContainer<S> remaining = pick.getRemaining(); Stream<Action<S>> result = picked .generateSolutions() .map(solutionContribution -> { S partialSolution = solutionCombiner.apply(baseSolution, solutionContribution); Action<S> r; //Stream<Action<S>> r; // If the partial solution is null, then indicate the // absence of a solution by returning a stream that yields // null as a 'solution' if (partialSolution == null) { //r = Collections.<S> singleton(null).stream(); r = null; } else { // This step is optional: it refines problems // based on the current partial solution // Depending on your setting, this can give a // performance boost or penalty //ProblemContainerImpl<S> openProblems = remaining; ProblemContainer<S> openProblems = remaining.refine(partialSolution); r = new ActionProblemContainer<S>(partialSolution, isUnsolveable, openProblems, solutionCombiner); // // if (openProblems.isEmpty()) { // r = Collections.<S> emptySet().stream(); // } else { // r = // //ProblemSolver<S> nextState = new ProblemSolver<S>(openProblems, baseSolution, solutionCombiner); // //r = nextState.streamSolutions(); // } } // Stream<Action<S>> s = r.map(x -> ); //<S>(partialSolution, partialSolution)); return r; }) ; return result; } }