More tweaks

This commit is contained in:
Naveen Sundar Govindarajulu 2017-01-15 18:54:56 -05:00
parent 598f9b3dff
commit f3ddd342c6
22 changed files with 710 additions and 175 deletions

View file

@ -14,10 +14,26 @@ import java.util.stream.Collectors;
public class DepthFirstPlanner implements Planner {
private static final int MAX_DEPTH = 4;
@Override
public Optional<Set<Plan>> plan(Set<Formula> background, Set<Action> actions, State start, State goal) {
return planInternal(Sets.newSet(), 0, background, actions, start, goal);
}
private Optional<Set<Plan>> planInternal(Set<Pair<State, Action>> history, int currentDepth, Set<Formula> background, Set<Action> actions, State start, State goal) {
if(currentDepth>=MAX_DEPTH){
return Optional.empty();
}
if (Operations.satisfies(background, start, goal)) {
//Already satisfied. Do nothing. Return a set with an empty plan.
return Optional.of(Sets.with(Plan.newEmptyPlan(goal, background)));
@ -29,29 +45,38 @@ public class DepthFirstPlanner implements Planner {
for (Action action : actions) {
Optional<Pair<State, Action>> nextStateActionPair = Operations.apply(background, action, start);
Optional<Set<Pair<State, Action>>> nextStateActionPairs = Operations.apply(background, action, start);
if (nextStateActionPair.isPresent()) {
if (nextStateActionPairs.isPresent()) {
Optional<Set<Plan>> planOpt = plan(background, actions, nextStateActionPair.get().first(), goal);
for (Pair<State, Action> stateActionPair : nextStateActionPairs.get()) {
if (planOpt.isPresent()) {
atleastOnePlanFound = true;
Set<Plan> nextPlans = planOpt.get();
State nextSate = nextStateActionPair.get().first();
Action instantiatedAction = nextStateActionPair.get().second();
Optional<Set<Plan>> planOpt = planInternal(history, currentDepth+1, background, actions, stateActionPair.first(), goal);
Set<Plan> augmentedPlans = nextPlans.stream().
map(plan -> plan.getPlanByStartingWith(instantiatedAction, nextSate)).
collect(Collectors.toSet());
if (planOpt.isPresent()) {
allPlans.addAll(augmentedPlans);
//TODO: store different plans and return the best plan.
atleastOnePlanFound = true;
Set<Plan> nextPlans = planOpt.get();
State nextSate = stateActionPair.first();
Action instantiatedAction = stateActionPair.second();
Set<Plan> augmentedPlans = nextPlans.stream().
map(plan -> plan.getPlanByStartingWith(instantiatedAction, nextSate)).
collect(Collectors.toSet());
allPlans.addAll(augmentedPlans);
//TODO: store different plans and return the best plan.
}
}
}
}
if (atleastOnePlanFound) {
@ -67,4 +92,5 @@ public class DepthFirstPlanner implements Planner {
}
}

View file

@ -1,5 +1,7 @@
package edu.rpi.rair;
import java.util.concurrent.atomic.AtomicInteger;
/**
* Created by naveensundarg on 1/14/17.
*/
@ -7,18 +9,36 @@ public class Goal {
private final State goalState;
private final int priority;
private final String name;
private static final AtomicInteger nameCounter;
static {
nameCounter = new AtomicInteger(0);
}
private Goal(State goalState, int priority) {
this.goalState = goalState;
this.priority = priority;
this.name = "G" + nameCounter.incrementAndGet();
}
private Goal(State goalState, int priority, String name) {
this.goalState = goalState;
this.priority = priority;
this.name = name;
}
public static Goal makeGoal(State goalState, int priority){
return new Goal(goalState, priority);
}
public static Goal makeGoal(State goalState, int priority, String name){
return new Goal(goalState, priority, name);
}
public State getGoalState() {
return goalState;
}
@ -27,11 +47,16 @@ public class Goal {
return priority;
}
public String getName() {
return name;
}
@Override
public String toString() {
return "Goal{" +
"goalState=" + goalState +
", priority=" + priority +
", name='" + name + '\'' +
'}';
}

View file

@ -14,6 +14,9 @@ import java.util.Set;
public class GoalTracker {
private final Set<Formula> background;
private State currentState;
private final Set<Goal> currentGoals;
@ -32,6 +35,7 @@ public class GoalTracker {
public boolean adoptGoal(Goal goal) {
Optional<Set<Plan>> possiblePlans = planner.plan(background, actions, currentState, goal.getGoalState());
if (!possiblePlans.isPresent()) {

View file

@ -3,9 +3,11 @@ package edu.rpi.rair;
import com.naveensundarg.shadow.prover.core.Prover;
import com.naveensundarg.shadow.prover.core.SnarkWrapper;
import com.naveensundarg.shadow.prover.representations.formula.And;
import com.naveensundarg.shadow.prover.representations.formula.BiConditional;
import com.naveensundarg.shadow.prover.representations.formula.Formula;
import com.naveensundarg.shadow.prover.representations.value.Value;
import com.naveensundarg.shadow.prover.representations.value.Variable;
import com.naveensundarg.shadow.prover.utils.CollectionUtils;
import com.naveensundarg.shadow.prover.utils.ImmutablePair;
import com.naveensundarg.shadow.prover.utils.Pair;
import com.naveensundarg.shadow.prover.utils.Sets;
@ -14,6 +16,7 @@ import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.concurrent.*;
import java.util.stream.Collectors;
import static edu.rpi.rair.State.FALSE;
@ -23,6 +26,7 @@ import static edu.rpi.rair.State.FALSE;
*/
public class Operations {
private static boolean DEEP_EQUIVALENCE = false;
private static Prover prover;
static{
@ -31,38 +35,125 @@ public class Operations {
public static synchronized Optional<Map<Variable, Value>> proveAndGetBindings(Set<Formula> givens, Formula goal, List<Variable> variables){
return prover.proveAndGetBindings(givens, goal, variables);
Future<Optional<Map<Variable, Value>>> future = new FutureTask<>(()->{
return prover.proveAndGetBindings(givens, goal, variables);
});
Optional<Map<Variable, Value>> answer;
try{
answer = future.get(1, TimeUnit.SECONDS);
} catch (InterruptedException | ExecutionException | TimeoutException e) {
answer = Optional.empty();
}
return answer;
}
public static Optional<Pair<State,Action>> apply(Set<Formula> background, Action action, State state){
Prover prover = new SnarkWrapper();
public static synchronized Optional<Set<Map<Variable, Value>>> proveAndGetMultipleBindings(Set<Formula> givens, Formula goal, List<Variable> variables){
return prover.proveAndGetMultipleBindings(givens, goal, variables);
/* Future<Optional<Set<Map<Variable, Value>>>> future = new FutureTask<>(()-> prover.proveAndGetMultipleBindings(givens, goal, variables));
Optional<Set<Map<Variable, Value>>> answer;
try{
answer = future.get(50, TimeUnit.SECONDS);
} catch (InterruptedException | ExecutionException | TimeoutException e ) {
answer = Optional.empty();
}
return answer;
*/
}
public static Optional<Set<Pair<State,Action>>> apply(Set<Formula> background, Action action, State state){
Set<Formula> givens = Sets.union(background, state.getFormulae());
Optional<Map<Variable, Value>> bingdingsOpt = proveAndGetBindings(givens, action.getPrecondition(), action.openVars());
Optional<Set<Map<Variable, Value>>> bindingsOpt = proveAndGetMultipleBindings(givens, action.getPrecondition(), action.openVars());
State newState;
if(!bingdingsOpt.isPresent()){
if(!bindingsOpt.isPresent()){
return Optional.empty();
}
Set<Pair<State,Action>> nexts = Sets.newSet();
for(Map<Variable, Value> binding: bindingsOpt.get()){
if(binding.values().stream().anyMatch(x-> x instanceof Variable)){
continue;
}
Set<Formula> instantiatedDeletions = action.instantiateDeletions(binding);
Set<Formula> formulaeToRemove = state.getFormulae().stream().
filter(f-> instantiatedDeletions.stream().anyMatch(d-> equivalent(background, f,d))).collect(Collectors.toSet());
Set<Formula> newFormulae = state.getFormulae();
newFormulae = Sets.union(newFormulae, action.instantiateAdditions(bingdingsOpt.get()));
newFormulae = Sets.union(newFormulae, action.instantiateAdditions(binding));
newFormulae = Sets.difference(newFormulae, formulaeToRemove);
newFormulae = Sets.difference(newFormulae, action.instantiateDeletions(bingdingsOpt.get()));
newState = State.initializeWith(newFormulae);
return Optional.of(ImmutablePair.from(newState, action.instantiate(bingdingsOpt.get())));
nexts.add(ImmutablePair.from(newState, action.instantiate(binding)));
}
if(nexts.isEmpty()){
Map<Variable, Value> emptyBinding = CollectionUtils.newMap();
Set<Formula> instantiatedDeletions = action.instantiateDeletions(emptyBinding);
Set<Formula> formulaeToRemove = state.getFormulae().stream().
filter(f-> instantiatedDeletions.stream().anyMatch(d-> equivalent(background, f,d))).collect(Collectors.toSet());
Set<Formula> newFormulae = state.getFormulae();
newFormulae = Sets.union(newFormulae, action.instantiateAdditions(emptyBinding));
newFormulae = Sets.difference(newFormulae, formulaeToRemove);
newState = State.initializeWith(newFormulae);
nexts.add(ImmutablePair.from(newState, action.instantiate(emptyBinding)));
}
return Optional.of(nexts);
}
public static boolean equivalent(Set<Formula> background, Formula f1, Formula f2){
if(!DEEP_EQUIVALENCE){
return f1.equals(f2);
}
BiConditional biConditional = new BiConditional(f1, f2);
return prover.prove(background,biConditional).isPresent();
}
public static boolean satisfies(Set<Formula> background, State state, State goal){

View file

@ -0,0 +1,96 @@
package edu.rpi.rair.utils;
import com.naveensundarg.shadow.prover.representations.formula.Formula;
import com.naveensundarg.shadow.prover.utils.CollectionUtils;
import com.naveensundarg.shadow.prover.utils.Reader;
import edu.rpi.rair.Goal;
import edu.rpi.rair.State;
import us.bpsm.edn.Keyword;
import us.bpsm.edn.parser.Parseable;
import us.bpsm.edn.parser.Parser;
import us.bpsm.edn.parser.Parsers;
import us.bpsm.edn.parser.Token;
import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.*;
/**
* Created by naveensundarg on 1/13/17.
*/
public class GoalTrackingProblem {
private final PlanningProblem planningProblem;
private final Set<Goal> goals;
private final Map<String, Goal> goalNameMap;
private static final Keyword DEFINITIONS = Keyword.newKeyword("definitions");
private static final Keyword GOALS = Keyword.newKeyword("goals");
private static final Keyword PRIORITY = Keyword.newKeyword("priority");
private static final Keyword STATE = Keyword.newKeyword("state");
public GoalTrackingProblem(PlanningProblem planningProblem, Set<Goal> goals) {
this.planningProblem = planningProblem;
this.goals = goals;
this.goalNameMap = CollectionUtils.newMap();
for(Goal g: goals){
goalNameMap.put(g.getName(), g);
}
}
public static List<GoalTrackingProblem> readFromFile(InputStream inputStream) throws Reader.ParsingException {
Parseable parseable = Parsers.newParseable(new InputStreamReader(inputStream));
Parser parser = Parsers.newParser(Parsers.defaultConfiguration());
List<GoalTrackingProblem> goalTrackingProblems = CollectionUtils.newEmptyList();
Object nextValue = parser.nextValue(parseable);
Set<Goal> goals = CollectionUtils.newEmptySet();
while (!nextValue.equals(Token.END_OF_INPUT)) {
Map<?, ?> goalTrackingProblemSpec = (Map<?, ?>) nextValue;
PlanningProblem planningProblem = PlanningProblem.readFromObject(goalTrackingProblemSpec.get(DEFINITIONS));
Map<?, ?> goalSpecs = (Map<?,?>) goalTrackingProblemSpec.get(GOALS);
for(Map.Entry<?,?> entry : goalSpecs.entrySet()){
String name = entry.getKey().toString();
Map<?, ?> goalSpec = (Map<?,?>)entry.getValue();
int priority = Math.toIntExact((Long) goalSpec.get(PRIORITY));
Set<Formula> stateFormulae = PlanningProblem.readFrom((List<?>) goalSpec.get(STATE));
goals.add(Goal.makeGoal(State.initializeWith(stateFormulae), priority, name));
}
goalTrackingProblems.add(new GoalTrackingProblem(planningProblem, goals));
nextValue = parser.nextValue(parseable);
}
return goalTrackingProblems;
}
public PlanningProblem getPlanningProblem() {
return planningProblem;
}
public Set<Goal> getGoals() {
return goals;
}
public Goal getGoalNamed(String goalName) {
return goalNameMap.get(goalName);
}
}

View file

@ -81,52 +81,7 @@ public class PlanningProblem {
while (!nextValue.equals(Token.END_OF_INPUT)) {
Map<?, ?> planningProblemSpec = (Map<?, ?>) nextValue;
Set<Formula> background = readFrom((List<?>) planningProblemSpec.get(BACKGROUND));
Set<Formula> start = readFrom((List<?>) planningProblemSpec.get(START));
Set<Formula> goal = readFrom((List<?>) planningProblemSpec.get(GOAL));
List<?> actionDefinitions = (List<?>) planningProblemSpec.get(ACTION);
String name = planningProblemSpec.get(NAME).toString();
Set<Action> actions = readActionsFrom(actionDefinitions);
Map<String, Action> actionMap = CollectionUtils.newMap();
actions.stream().forEach(action->{
actionMap.put(action.getName(), action);
});
if(planningProblemSpec.containsKey(EXPECTED_PLANS)){
List<?> plans = (List<?>) planningProblemSpec.get(EXPECTED_PLANS);
Set<List<Action>> expectedActions = plans.stream().map(plan->{
List<?> instantActionList = (List<?>) plan;
List<Action> actionsList = instantActionList.stream().map(x -> {
try {
return readInstantiatedAction(actionMap, x);
} catch (Reader.ParsingException e) {
return null;
}
}).collect(Collectors.toList());
if(actionsList.stream().anyMatch(Objects::isNull)){
return null;
} else {
return actionsList;
}
}).collect(Collectors.toSet());
planningProblems.add(new PlanningProblem(name, background, State.initializeWith(start),
State.initializeWith(goal), actions, expectedActions));
} else {
planningProblems.add(new PlanningProblem(name, background, State.initializeWith(start),
State.initializeWith(goal), actions));
}
planningProblems.add(readFromObject(nextValue));
@ -137,6 +92,56 @@ public class PlanningProblem {
}
public static PlanningProblem readFromObject(Object nextValue) throws Reader.ParsingException {
Map<?, ?> planningProblemSpec = (Map<?,?>)nextValue;
Set<Formula> background = readFrom((List<?>) planningProblemSpec.get(BACKGROUND));
Set<Formula> start = readFrom((List<?>) planningProblemSpec.get(START));
Set<Formula> goal = readFrom((List<?>) planningProblemSpec.get(GOAL));
List<?> actionDefinitions = (List<?>) planningProblemSpec.get(ACTION);
String name = planningProblemSpec.get(NAME).toString();
Set<Action> actions = readActionsFrom(actionDefinitions);
Map<String, Action> actionMap = CollectionUtils.newMap();
actions.stream().forEach(action->{
actionMap.put(action.getName(), action);
});
if(planningProblemSpec.containsKey(EXPECTED_PLANS)){
List<?> plans = (List<?>) planningProblemSpec.get(EXPECTED_PLANS);
Set<List<Action>> expectedActions = plans.stream().map(plan->{
List<?> instantActionList = (List<?>) plan;
List<Action> actionsList = instantActionList.stream().map(x -> {
try {
return readInstantiatedAction(actionMap, x);
} catch (Reader.ParsingException e) {
return null;
}
}).collect(Collectors.toList());
if(actionsList.stream().anyMatch(Objects::isNull)){
return null;
} else {
return actionsList;
}
}).collect(Collectors.toSet());
return new PlanningProblem(name, background, State.initializeWith(start),
State.initializeWith(goal), actions, expectedActions);
} else {
return new PlanningProblem(name, background, State.initializeWith(start),
State.initializeWith(goal), actions);
}
}
private static Action readInstantiatedAction(Map<String, Action> actionMap, Object instantiatedActionSpec) throws Reader.ParsingException {
@ -222,7 +227,7 @@ public class PlanningProblem {
}
private static Set<Formula> readFrom(List<?> objects) throws Reader.ParsingException {
public static Set<Formula> readFrom(List<?> objects) throws Reader.ParsingException {
Set<Formula> formulae = objects.stream().map(x -> {
try {

View file

@ -0,0 +1,55 @@
package edu.rpi.rair.utils;
import com.diogonunes.jcdp.color.ColoredPrinter;
import com.diogonunes.jcdp.color.api.Ansi;
import com.naveensundarg.shadow.prover.utils.Reader;
import edu.rpi.rair.GoalTracker;
import edu.rpi.rair.Planner;
import java.util.List;
/**
* Created by naveensundarg on 1/15/17.
*/
public class RunDemo {
public static void main(String[] args) throws Reader.ParsingException {
List<GoalTrackingProblem> goalTrackingProblemList = (GoalTrackingProblem.readFromFile(Planner.class.getResourceAsStream("goal_tracking_tests.clj")));
GoalTrackingProblem goalTrackingProblem = goalTrackingProblemList.get(0);
GoalTracker goalTracker = new GoalTracker(goalTrackingProblem.getPlanningProblem().getBackground(),
goalTrackingProblem.getPlanningProblem().getStart(),
goalTrackingProblem.getPlanningProblem().getActions());
ColoredPrinter cp = new ColoredPrinter.Builder(1, false).build();
cp.setForegroundColor(Ansi.FColor.WHITE);
cp.setBackgroundColor(Ansi.BColor.BLUE); //setting format
cp.println("Adding goal G1");
cp.clear();
boolean res1 = goalTracker.adoptGoal(goalTrackingProblem.getGoalNamed("G1"));
cp.setForegroundColor(Ansi.FColor.WHITE);
cp.setBackgroundColor(Ansi.BColor.BLUE); //setting format
cp.println("Adding goal G2");
cp.clear();
goalTracker.adoptGoal(goalTrackingProblem.getGoalNamed("G2"));
cp.setForegroundColor(Ansi.FColor.WHITE);
cp.setBackgroundColor(Ansi.BColor.BLUE); //setting format
cp.println("Adding goal G3");
cp.clear();
goalTracker.adoptGoal(goalTrackingProblem.getGoalNamed("G3"));
}
}