package aima.core.logic.propositional.inference;
import java.util.List;
import java.util.Set;
import aima.core.agent.Action;
import aima.core.logic.propositional.kb.data.Clause;
import aima.core.logic.propositional.kb.data.Model;
import aima.core.logic.propositional.parsing.ast.ComplexSentence;
import aima.core.logic.propositional.parsing.ast.Sentence;
import aima.core.logic.propositional.visitors.ConvertToConjunctionOfClauses;
/**
* Artificial Intelligence A Modern Approach (3rd Edition): page 261.<br>
* <br>
*
* <pre>
* <code>
* function SATPlan(init, transition, goal, T<sub>max</sub>) returns solution or failure
* inputs: init, transition, goal, constitute a description of the problem
* T<sub>max</sub>, an upper limit for plan length
*
* for t = 0 to T<sub>max</sub> do
* cnf ← TRANSLATE-TO-SAT(init, transition, goal, t)
* model ← SAT-SOLVER(cnf)
* if model is not null then
* return EXTRACT-SOLUTION(model)
* return failure
* </code>
* </pre>
*
* Figure 7.22 The SATPlan algorithm. The planning problem is translated into a CNF
* sentence in which the goal is asserted to hold at a fixed time step t and axioms are included
* for each time step up to t. If the satisfiability algorithm finds a model, then a plan is
* extracted by looking at those proposition symbols that refer to actions and are assigned true
* in the model. If no model exists, then the process is repeated with the goal moved one step later.
*
* @author Ciaran O'Reilly
*/
public class SATPlan {
/**
* function SATPlan(init, transition, goal, T<sub>max</sub>) returns
* solution or failure<br>
*
* @param init
* provides a collection of assertions about the initial state.
* @param transition
* provides the successor-state axioms for all possible actions
* at each time step up to some maximum t.
* @param goal
* provides the assertion that the goal is achieved at time t.
* @param tMax
* the maximum number of time steps in which the goal is to be
* achieved in.
* @return a list of actions describing a solution for the given problem or
* null if no solution is found (i.e failure)
*/
public List<Action> satPlan(Describe init, Describe transition, Describe goal, int tMax) {
// for t = 0 to T<sub>max</sub> do
for (int t = 0; t <= tMax; t++) {
// cnf ← TRANSLATE-TO-SAT(init, transition, goal, t)
Set<Clause> cnf = translateToSAT(init, transition, goal, t);
// model ← SAT-SOLVER(cnf)
Model model = satSolver.solve(cnf);
// if model is not null then
if (model != null) {
// return EXTRACT-SOLUTION(model)
return solutionExtractor.extractSolution(model);
}
}
// return failure
return null;
}
//
// SUPPORTING CODE
/**
* Interface to be implemented to describe different aspects of a given problem.
*
*/
interface Describe {
Sentence assertions(int t);
}
/**
* Interface to be implemented to extract a solution from a satisfiable model.
*
*/
interface SolutionExtractor {
List<Action> extractSolution(Model model);
}
private SATSolver satSolver = null;
private SolutionExtractor solutionExtractor = null;
public SATPlan(SATSolver satSolver, SolutionExtractor solutionExtractor) {
this.satSolver = satSolver;
this.solutionExtractor = solutionExtractor;
}
//
// PROTECTED
//
protected Set<Clause> translateToSAT(Describe init, Describe transition, Describe goal, int t) {
Sentence s = ComplexSentence.newConjunction(init.assertions(t), transition.assertions(t), goal.assertions(t));
return ConvertToConjunctionOfClauses.convert(s).getClauses();
}
}