Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance. Project price only 1 $
You can buy this project and download/modify it how often you want.
package ai.libs.jaicore.planning.classical.algorithms.strips.forward;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import ai.libs.jaicore.logic.fol.structure.CNFFormula;
import ai.libs.jaicore.logic.fol.structure.Clause;
import ai.libs.jaicore.logic.fol.structure.ConstantParam;
import ai.libs.jaicore.logic.fol.structure.Literal;
import ai.libs.jaicore.logic.fol.structure.LiteralParam;
import ai.libs.jaicore.logic.fol.structure.Monom;
import ai.libs.jaicore.logic.fol.structure.VariableParam;
import ai.libs.jaicore.logic.fol.util.ForwardChainer;
import ai.libs.jaicore.logic.fol.util.ForwardChainingProblem;
import ai.libs.jaicore.logic.fol.util.NextBindingFoundEvent;
import ai.libs.jaicore.planning.classical.problems.ce.CEAction;
import ai.libs.jaicore.planning.classical.problems.ce.CEOperation;
import ai.libs.jaicore.planning.classical.problems.strips.Operation;
import ai.libs.jaicore.planning.classical.problems.strips.StripsAction;
import ai.libs.jaicore.planning.classical.problems.strips.StripsOperation;
import ai.libs.jaicore.planning.classical.problems.strips.StripsPlanningDomain;
import ai.libs.jaicore.planning.core.Action;
import ai.libs.jaicore.planning.core.Plan;
public class StripsUtil {
private static final Logger logger = LoggerFactory.getLogger(StripsUtil.class);
public static List getApplicableActionsInState(final Monom state, final StripsPlanningDomain domain) {
return getApplicableActionsInState(state, domain, false, -1);
}
public static List getApplicableActionsInState(final Monom state, final StripsPlanningDomain domain, final boolean randomized, final int pLimit) {
long start = System.currentTimeMillis();
int limit = pLimit;
logger.debug("Computing applicable actions for state with {} items (activate TRACE for exact state)", state.size());
logger.trace("Exact state is {}", state);
List applicableDerivedActions = new ArrayList<>();
Collection operations = domain.getOperations();
/* if the computation should be randomized, shuffle operations first */
if (randomized) {
if (!(operations instanceof List)) {
operations = new ArrayList<>(operations);
}
Collections.shuffle((List)operations);
}
/* now walk over the operations and collect actions until the limit is reached */
long timeToOrderOps = System.currentTimeMillis() - start;
for (Operation op : domain.getOperations()) {
Collection candidates = getPossibleOperationGroundingsForState(state, (StripsOperation) op, limit);
applicableDerivedActions.addAll(candidates);
if (limit >= 0) {
limit = Math.max(0, limit - candidates.size());
}
}
long duration = System.currentTimeMillis() - start;
logger.debug("Done. Computation of {} applicable actions took {}ms of which {}ms were used to order the operations", applicableDerivedActions.size(), duration, timeToOrderOps);
return applicableDerivedActions;
}
public static Collection getPossibleOperationGroundingsForState(final Monom state, final StripsOperation operation, final int limit) {
Collection applicableDerivedActions = new ArrayList<>();
/* decompose premise in positive and negative literals */
logger.debug("Compute all groundings of {}-premise that can be inferred from state with {} items (activate TRACE for exact premise and state)", operation.getPrecondition().size(), state.size());
logger.trace("Exact premise is {}", operation.getPrecondition());
logger.trace("Exact state is {}", state);
long start = System.currentTimeMillis();
ForwardChainer fc = new ForwardChainer(new ForwardChainingProblem(state, operation.getPrecondition(), true));
long fcPreparationTime = System.currentTimeMillis() - start;
NextBindingFoundEvent event;
try {
int i = 0;
while ((event = fc.nextBinding()) != null && (limit < 0 || (i++ < limit))) {
Map grounding = event.getGrounding();
/* refactor grounding to constants only and add the respective action */
Map rGrounding = new HashMap<>();
for (Entry groundingEntry : grounding.entrySet()) {
ConstantParam cp = (ConstantParam)groundingEntry.getValue();
rGrounding.put(groundingEntry.getKey(), cp);
}
StripsAction a = new StripsAction(operation, rGrounding);
applicableDerivedActions.add(a);
logger.debug("Found action {} to be applicable after {}ms.", a.getEncoding(), System.currentTimeMillis() - start);
}
} catch (Exception e) {
logger.error("Error in grounding computation: {}", e);
}
logger.info("Determined {}/{} applicable actions within {}ms of which preparing the FC algorithm consumed {}ms.", applicableDerivedActions.size(), limit, System.currentTimeMillis() - start, fcPreparationTime);
return applicableDerivedActions;
}
public static void updateState(final Monom state, final Action appliedAction) {
/* apply effects of action (STRIPS) */
if (appliedAction.getOperation() instanceof StripsOperation) {
Action a = new StripsAction((StripsOperation) appliedAction.getOperation(), appliedAction.getGrounding());
state.removeAll(((StripsAction) a).getDeleteList());
state.addAll(((StripsAction) a).getAddList());
}
/* apply effects of action (ConditionalEffect operations) */
else if (appliedAction.getOperation() instanceof CEOperation) {
CEAction a = new CEAction((CEOperation) appliedAction.getOperation(), appliedAction.getGrounding());
Map addLists = a.getAddLists();
/* determine literals to remove */
Map deleteLists = a.getDeleteLists();
Collection toRemove = new ArrayList<>();
for (CNFFormula condition : deleteLists.keySet()) {
if (condition.entailedBy(state)) {
toRemove.addAll(deleteLists.get(condition));
}
}
/* determine literals to add */
Collection toAdd = new ArrayList<>();
for (CNFFormula condition : addLists.keySet()) {
/* evaluate interpreted predicates */
CNFFormula modifiedCondition = new CNFFormula();
boolean conditionIsSatisfiable = true;
for (Clause c : condition) {
Clause modifiedClause = new Clause();
boolean clauseContainsTrue = false;
for (Literal l : c) {
modifiedClause.add(l);
/* if the clause is not empty, add it to the condition */
if (!clauseContainsTrue) {
if (!modifiedClause.isEmpty()) {
modifiedCondition.add(modifiedClause);
} else {
conditionIsSatisfiable = false;
break;
}
}
}
}
if (conditionIsSatisfiable && modifiedCondition.entailedBy(state)) {
toAdd.addAll(addLists.get(condition));
}
}
/* now conduct update */
state.removeAll(toRemove);
state.addAll(toAdd);
} else {
logger.error("No support for operations of class {}", appliedAction.getOperation().getClass());
}
}
public static Monom getStateAfterPlanExecution(final Monom initState, final Plan plan) {
Monom state = new Monom(initState);
plan.getActions().forEach(a -> updateState(state, a));
return state;
}
}