/** * This method is the access point to the planning procedure. Initially, it adds all variables * from axioms to the set of found vars, then does the linear planning. If lp does not solve the * problem and there are subtasks, goal-driven recursive planning with backtracking is invoked. * Planning is performed until no new variables are introduced into the algorithm. */ public EvaluationAlgorithm invokePlaning(Problem problem, boolean _computeAll) { long startTime = System.currentTimeMillis(); computeAll = _computeAll; EvaluationAlgorithm algorithm = new EvaluationAlgorithm(); PlanningContext context = problem.getCurrentContext(); // add all axioms at the beginning of an algorithm Collection<Var> flattened = new HashSet<Var>(); for (Iterator<Rel> axiomIter = problem.getAxioms().iterator(); axiomIter.hasNext(); ) { Rel rel = axiomIter.next(); unfoldVarsToSet(rel.getOutputs(), flattened); // do not overwrite values of variables that come via args of compute() or as inputs of // independent subtasks if (!problem.getAssumptions().containsAll(flattened) // do not overwrite values of already known variables. // typically this is the case when a value of a variable // is given in a scheme via a properties window // && !problem.getKnownVars().containsAll( flattened ) ) { algorithm.addRel(rel); } axiomIter.remove(); context.getKnownVars().addAll(flattened); flattened.clear(); } context.getFoundVars().addAll(context.getKnownVars()); // remove all known vars with no relations for (Iterator<Var> varIter = context.getKnownVars().iterator(); varIter.hasNext(); ) { if (varIter.next().getRels().isEmpty()) { varIter.remove(); } } // start planning if (problem.getRelsWithSubtasks().isEmpty() && linearForwardSearch(context, algorithm, computeAll)) { if (isLinearLoggingOn()) logger.debug("Problem solved without subtasks"); } else if (!problem.getRelsWithSubtasks().isEmpty() && subtaskPlanning(problem, algorithm)) { if (isLinearLoggingOn()) logger.debug("Problem solved with subtasks"); } else if (!computeAll) { if (isLinearLoggingOn()) logger.debug("Problem not solved"); } if (!nested) { logger.info("Planning time: " + (System.currentTimeMillis() - startTime) + "ms."); } return algorithm; }
/** * Linear forward search algorithm * * @param p * @param algorithm * @param targetVars * @param _computeAll * @return */ private boolean linearForwardSearch( PlanningContext context, EvaluationAlgorithm algorithm, boolean _computeAll) { /* * while iterating through hashset, items cant be removed from/added to * that set. Theyre collected into these sets and added/removedall * together after iteration is finished */ Set<Var> newVars = new LinkedHashSet<Var>(); Set<Var> relOutputs = new LinkedHashSet<Var>(); Set<Var> removableVars = new LinkedHashSet<Var>(); boolean changed = true; if (isLinearLoggingOn()) logger.debug( "------Starting linear planning with (sub)goals: " + context.getRemainingGoals() + "--------"); if (isLinearLoggingOn()) logger.debug("Algorithm " + algorithm); int counter = 1; while ((!_computeAll && changed && !context.getRemainingGoals().isEmpty()) || (changed && _computeAll)) { if (isLinearLoggingOn()) logger.debug("----Iteration " + counter + " ----"); counter++; changed = false; // iterate through all knownvars if (isLinearLoggingOn()) logger.debug("Known:" + context.getKnownVars()); for (Var var : context.getKnownVars()) { if (isLinearLoggingOn()) logger.debug("Current Known: " + var); // Check the relations of all components for (Rel rel : var.getRels()) { if (isLinearLoggingOn()) logger.debug("And its rel: " + rel); if (context.isAvailableRel(rel)) { context.removeUnknownInput(rel, var); if (isLinearLoggingOn()) logger.debug("problem contains it " + rel); removableVars.add(var); if (context.isRelReadyToUse(rel) && rel.getType() != RelType.TYPE_METHOD_WITH_SUBTASK) { if (isLinearLoggingOn()) logger.debug("rel is ready to be used " + rel); boolean relIsNeeded = false; if (isLinearLoggingOn()) logger.debug("its outputs " + rel.getOutputs()); for (Var relVar : rel.getOutputs()) { if (!context.getFoundVars().contains(relVar)) { relIsNeeded = true; } } if (rel.getOutputs().isEmpty()) { relIsNeeded = true; } if (isLinearLoggingOn()) logger.debug("relIsNeeded " + relIsNeeded); if (relIsNeeded) { if (isLinearLoggingOn()) logger.debug("needed rel: " + rel); if (!rel.getOutputs().isEmpty()) { relOutputs.clear(); unfoldVarsToSet(rel.getOutputs(), relOutputs); newVars.addAll(relOutputs); context.getFoundVars().addAll(relOutputs); } algorithm.addRel(rel); if (isLinearLoggingOn()) logger.debug("algorithm " + algorithm); } context.removeRel(rel); changed = true; } } } } // remove targets if they have already been found for (Iterator<Var> targetIter = context.getRemainingGoals().iterator(); targetIter.hasNext(); ) { Var targetVar = targetIter.next(); if (context.getFoundVars().contains(targetVar)) { targetIter.remove(); } } if (isLinearLoggingOn()) logger.debug("foundvars " + context.getFoundVars()); context.getKnownVars().addAll(newVars); context.getKnownVars().removeAll(removableVars); newVars.clear(); } if (isLinearLoggingOn()) logger.debug("algorithm " + algorithm); if (!_computeAll) { Optimizer.optimize(context, algorithm); if (isLinearLoggingOn()) logger.debug("optimized algorithm " + algorithm); } if (isLinearLoggingOn()) logger.debug("\n---!!!Finished linear planning!!!---\n"); return context.getRemainingGoals().isEmpty() || context.getFoundVars().containsAll(context.getAllGoals()); }