diff --git a/src/main/java/edu/rpi/rair/Goal.java b/src/main/java/edu/rpi/rair/Goal.java index bc4c36e..31e6a3e 100644 --- a/src/main/java/edu/rpi/rair/Goal.java +++ b/src/main/java/edu/rpi/rair/Goal.java @@ -8,31 +8,31 @@ import java.util.concurrent.atomic.AtomicInteger; public class Goal { private final State goalState; - private final int priority; + private final double priority; private final String name; private static final AtomicInteger nameCounter; static { nameCounter = new AtomicInteger(0); } - private Goal(State goalState, int priority) { + private Goal(State goalState, double priority) { this.goalState = goalState; this.priority = priority; this.name = "G" + nameCounter.incrementAndGet(); } - private Goal(State goalState, int priority, String name) { + private Goal(State goalState, double priority, String name) { this.goalState = goalState; this.priority = priority; this.name = name; } - public static Goal makeGoal(State goalState, int priority){ + public static Goal makeGoal(State goalState, double priority){ return new Goal(goalState, priority); } - public static Goal makeGoal(State goalState, int priority, String name){ + public static Goal makeGoal(State goalState, double priority, String name){ return new Goal(goalState, priority, name); @@ -43,7 +43,7 @@ public class Goal { return goalState; } - public int getPriority() { + public double getPriority() { return priority; } @@ -67,14 +67,19 @@ public class Goal { Goal goal = (Goal) o; - if (priority != goal.priority) return false; - return goalState.equals(goal.goalState); + if (Double.compare(goal.priority, priority) != 0) return false; + if (goalState != null ? !goalState.equals(goal.goalState) : goal.goalState != null) return false; + return name != null ? name.equals(goal.name) : goal.name == null; } @Override public int hashCode() { - int result = goalState.hashCode(); - result = 31 * result + priority; + int result; + long temp; + result = goalState != null ? goalState.hashCode() : 0; + temp = Double.doubleToLongBits(priority); + result = 31 * result + (int) (temp ^ (temp >>> 32)); + result = 31 * result + (name != null ? name.hashCode() : 0); return result; } } diff --git a/src/main/java/edu/rpi/rair/GoalTracker.java b/src/main/java/edu/rpi/rair/GoalTracker.java index e979c8f..a486463 100644 --- a/src/main/java/edu/rpi/rair/GoalTracker.java +++ b/src/main/java/edu/rpi/rair/GoalTracker.java @@ -32,7 +32,7 @@ public class GoalTracker { } - public boolean adoptGoal(Goal goal) { + public Optional adoptGoal(Goal goal) { @@ -40,7 +40,7 @@ public class GoalTracker { if (!possiblePlans.isPresent()) { - return false; + return Optional.empty(); } else if (possiblePlans.get().isEmpty()) { @@ -50,14 +50,16 @@ public class GoalTracker { Set plans = possiblePlans.get(); + Optional noConflictPlan = plans.stream().filter(plan -> plan.noConflicts(currentGoals)).findAny(); - if (plans.stream().anyMatch(plan -> plan.noConflicts(currentGoals))) { + + if (noConflictPlan.isPresent()) { /* * If there is any plan without any goal conflicts, then adopt the goal. */ currentGoals.add(goal); - return true; + return noConflictPlan; } else { @@ -70,32 +72,34 @@ public class GoalTracker { */ boolean feasiblePlanExists = false; - int bestPriorityGap = 0; + double bestPriorityGap = 0; Set bestRemovalCandidates = null; + Plan feasiblePlan = null; for (Plan plan : plans) { Set conflictingGoals = plan.getConflictingGoals(currentGoals); - int conflictSum = conflictingGoals.stream().mapToInt(Goal::getPriority).sum(); - int gap = goal.getPriority() - conflictSum; + double conflictSum = conflictingGoals.stream().mapToDouble(Goal::getPriority).sum(); + double gap = goal.getPriority() - conflictSum; if(gap > 0 && gap > bestPriorityGap ){ feasiblePlanExists = true; bestPriorityGap = gap; + feasiblePlan = plan; bestRemovalCandidates= conflictingGoals; } } - if(feasiblePlanExists){ + if(feasiblePlan!=null){ currentGoals.removeAll(bestRemovalCandidates); currentGoals.add(goal); - return true; + return Optional.of(feasiblePlan); } else { - return false; + return Optional.empty(); } @@ -107,5 +111,7 @@ public class GoalTracker { } - + public Set getCurrentGoals() { + return currentGoals; + } } diff --git a/src/main/java/edu/rpi/rair/utils/GoalTrackingProblem.java b/src/main/java/edu/rpi/rair/utils/GoalTrackingProblem.java index 94104b7..6417aa1 100644 --- a/src/main/java/edu/rpi/rair/utils/GoalTrackingProblem.java +++ b/src/main/java/edu/rpi/rair/utils/GoalTrackingProblem.java @@ -66,7 +66,7 @@ public class GoalTrackingProblem { String name = entry.getKey().toString(); Map goalSpec = (Map)entry.getValue(); - int priority = Math.toIntExact((Long) goalSpec.get(PRIORITY)); + double priority = ((Double) goalSpec.get(PRIORITY)); Set stateFormulae = PlanningProblem.readFrom((List) goalSpec.get(STATE)); goals.add(Goal.makeGoal(State.initializeWith(stateFormulae), priority, name)); diff --git a/src/main/java/edu/rpi/rair/utils/RunDemo.java b/src/main/java/edu/rpi/rair/utils/RunDemo.java index 082cb1c..777dcdd 100644 --- a/src/main/java/edu/rpi/rair/utils/RunDemo.java +++ b/src/main/java/edu/rpi/rair/utils/RunDemo.java @@ -3,17 +3,24 @@ 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.Goal; import edu.rpi.rair.GoalTracker; +import edu.rpi.rair.Plan; import edu.rpi.rair.Planner; import java.util.List; +import java.util.Optional; +import java.util.stream.Collectors; /** * Created by naveensundarg on 1/15/17. */ public class RunDemo { - public static void main(String[] args) throws Reader.ParsingException { + static ColoredPrinter cp = new ColoredPrinter.Builder(1, false).build(); + + public static void main(String[] args) throws Reader.ParsingException { + List goalTrackingProblemList = (GoalTrackingProblem.readFromFile(Planner.class.getResourceAsStream("goal_tracking_tests.clj"))); @@ -25,31 +32,104 @@ public class RunDemo { 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")); + Goal g1 = goalTrackingProblem.getGoalNamed("G1"); + Goal g2 = goalTrackingProblem.getGoalNamed("G2"); + Goal g3 = goalTrackingProblem.getGoalNamed("G3"); + Goal g4 = goalTrackingProblem.getGoalNamed("G4"); + Goal g5 = goalTrackingProblem.getGoalNamed("G5"); + tryAndAddGoal(g1, goalTracker); + tryAndAddGoal(g2, goalTracker); + tryAndAddGoal(g3, goalTracker); + tryAndAddGoal(g4, goalTracker); + tryAndAddGoal(g5, goalTracker); } + static void tryAndAddGoal(Goal g, GoalTracker goalTracker) { + + System.out.println("========================"); + printInfo("Trying to Add Goal:", g.getName()); + + Optional possibleGoalPlan = goalTracker.adoptGoal(g); + if (possibleGoalPlan.isPresent()) { + + printSuccess("Successfully added:" , g.getName()); + printDebug1("Current Goals:" , goalTracker.getCurrentGoals().stream().map(Goal::getName).collect(Collectors.toSet()).toString()); + Plan plan = possibleGoalPlan.get(); + printDebug2("Plan:" , plan.getActions().isEmpty()? "No plan needed. Already satisfied." : plan.getActions().toString() ); + + } else { + + printFailure("Could not add " + g.getName()); + printDebug1("Current Goals: " , goalTracker.getCurrentGoals().stream().map(Goal::getName).collect(Collectors.toSet()).toString()); + + } + + } + + static void printInfo(String header, String message) { + + cp.setForegroundColor(Ansi.FColor.WHITE); + cp.setBackgroundColor(Ansi.BColor.BLUE); //setting format + cp.print(header); + cp.clear(); + cp.print(" "); + cp.setAttribute(Ansi.Attribute.BOLD); + cp.print(message); + cp.println(""); + cp.clear(); + } + + static void printSuccess(String header, String message) { + + cp.setForegroundColor(Ansi.FColor.BLACK); + cp.setBackgroundColor(Ansi.BColor.GREEN); //setting format + cp.print(header); + cp.clear(); + cp.print(" "); + cp.setAttribute(Ansi.Attribute.BOLD); + cp.print(message); + cp.println(""); + cp.clear(); + } + + + + + static void printDebug1(String header, String message) { + + cp.setForegroundColor(Ansi.FColor.BLACK); + cp.setBackgroundColor(Ansi.BColor.YELLOW); //setting format + cp.print(header); + cp.clear(); + cp.print(" "); + cp.setAttribute(Ansi.Attribute.BOLD); + cp.print(message); + cp.println(""); + cp.clear(); + } + + static void printDebug2(String header, String message) { + + cp.setForegroundColor(Ansi.FColor.BLACK); + cp.setBackgroundColor(Ansi.BColor.MAGENTA); //setting format + cp.print(header); + cp.clear(); + cp.print(" "); + cp.setAttribute(Ansi.Attribute.BOLD); + cp.print(message); + cp.println(""); + cp.clear(); + } + static void printFailure(String message) { + + cp.setForegroundColor(Ansi.FColor.WHITE); + cp.setBackgroundColor(Ansi.BColor.RED); //setting format + cp.print(message); + cp.clear(); + cp.println(""); + cp.clear(); + } } diff --git a/src/main/resources/edu/rpi/rair/completeness_problems.clj b/src/main/resources/edu/rpi/rair/completeness_problems.clj index b006894..0a016df 100644 --- a/src/main/resources/edu/rpi/rair/completeness_problems.clj +++ b/src/main/resources/edu/rpi/rair/completeness_problems.clj @@ -127,7 +127,9 @@ (in prisoner room1) (open (door room2)) (not (open (door room1)))] + :goal [(interrogates commander prisoner)] + :actions [(define-action open-door [?room] {:preconditions [(not (open (door ?room)))] @@ -135,7 +137,8 @@ :deletions [(not (open (door ?room)))]}) - (define-action accompany[?person ?room1 ?room2] + + (define-action accompany [?person ?room1 ?room2] {:preconditions [(not (= ?room1 ?room2)) (in ?person ?room1) (in self ?room1) @@ -144,17 +147,18 @@ :additions [(in ?person ?room2) (in self ?room2)] + :deletions [(in ?person ?room1) (in self ?room1)]}) - (define-action request-move [?person ?room2 ?room1] + (define-action move [?person ?room2 ?room1] {:preconditions [(not (= ?room1 ?room2)) (in ?person ?room2) - (not (= ?person prisoner)) (open (door ?room1)) (open (door ?room2))] :additions [(in ?person ?room1)] + :deletions [(in ?person ?room2)]}) (define-action get-interrogated [?room] @@ -162,23 +166,20 @@ (in prisoner ?room)] :additions [(interrogates commander prisoner)] + :deletions []}) ] - :expected-plans ( + :expected-plans ([(open-door room1) + (move commander room2 room1) + (get-interrogated room1)] [(open-door room1) - (request-move commander room2 room1) - (get-interrogated room1) - ] + (move prisoner room1 room2) + (get-interrogated room2)] [(open-door room1) (accompany prisoner room1 room2) - (get-interrogated room2) - ] - - ) - - } + (get-interrogated room2)])} diff --git a/src/main/resources/edu/rpi/rair/goal_tracking_tests.clj b/src/main/resources/edu/rpi/rair/goal_tracking_tests.clj index 1cbd653..7a7e6eb 100644 --- a/src/main/resources/edu/rpi/rair/goal_tracking_tests.clj +++ b/src/main/resources/edu/rpi/rair/goal_tracking_tests.clj @@ -1,62 +1,84 @@ {:definitions - {:name "Moving Between Rooms" - :background [(not (= room1 room2)) - (forall [?x] (iff (Locked ?x) (not (Open ?x)))) - (forall [?x ?y ?z] (if (and (In ?x ?y) (not (= ?z ?y))) - (not (In ?x ?z))))] - :start [(In self room1) - (In commander room2) - (In prisoner room1) - (Open (door room2)) - (not (Open (door room1)))] - :goal [] - :actions - [(define-action open-door [?room] - {:preconditions [(not (Open (door ?room)))] - :additions [(Open (door ?room))] - :deletions [(not (Open (door ?room)))]}) + {:name "demo 1" + :background [ + (forall [?x ?room1 ?room2] + (if (not (= ?room1 ?room2)) + (if (in ?x ?room1) (not (in ?x ?room2))) )) + (not (= room1 room2)) + (not (= prisoner commander)) + (not (= self prisoner)) + (not (= self commander)) + (person prisoner) + (person commander) + ] + :start [(in self room1) + (in commander room2) + (in prisoner room1) + (open (door room2)) + (not (open (door room1)))] - (define-action move-thing-from-to [?thing ?room1 ?room2] - {:preconditions [(not (= ?room1 ?room2)) - (In ?thing ?room1) - (Open (door ?room1)) - (Open (door ?room2))] + :goal [] - :additions [(In ?thing ?room2)] - :deletions [(In ?thing ?room1) - (In self ?room1)]}) - (define-action accompany-from-to [?thing ?room1 ?room2] - {:preconditions [(not (= ?room1 ?room2)) - (In self ?room1) - (In ?thing ?room1) - (Open (door ?room1)) - (Open (door ?room2))] + :actions + [(define-action open-door [?room] + {:preconditions [(not (open (door ?room)))] + :additions [(open (door ?room))] + :deletions [(not (open (door ?room)))]}) - :additions [(In ?thing ?room2) - (In ?self ?room2)] - :deletions [(In ?thing ?room1) - (In self ?room1)]}) - (define-action interrogate [?A ?B] - {:preconditions [(In ?room ?A) - (In ?room ?B)] - :additions [(Interrogates ?A ?B)] - :deletions [(In ?thing ?room1) - (In self ?room1)]})] + (define-action accompany [?person ?room1 ?room2] + {:preconditions [(not (= ?room1 ?room2)) + (in ?person ?room1) + (in self ?room1) + (open (door ?room1)) + (open (door ?room2))] + + :additions [(in ?person ?room2) + (in self ?room2)] + + :deletions [(in ?person ?room1) + (in self ?room1)]}) + + (define-action move [?person ?room2 ?room1] + {:preconditions [(not (= ?room1 ?room2)) + (in ?person ?room2) + (open (door ?room1)) + (open (door ?room2))] + + :additions [(in ?person ?room1)] + + :deletions [(in ?person ?room2)]}) + + (define-action get-interrogated [?room] + {:preconditions [(in commander ?room) + (in prisoner ?room)] + + :additions [(interrogates commander prisoner)] + + :deletions []}) + ] } - :goals {G1 {:priority 1 - :state [(not (Open (door room1)))]} + :goals {G1 {:priority 1.0 + :state [(not (open (door room1)))]} - G2 {:priority 1 - :state [(In prisoner room1)]} + G2 {:priority 1.0 + :state [(in prisoner room1)]} - G3 {:priority 1 + G3 {:priority 1.0 :state [(forall [?room] - (if (In prisoner ?room) - (In self ?room)))] - } + (if (in prisoner ?room) + (in self ?room)))]} + + G4 {:priority 2.0 + + :state [(interrogates commander prisoner)]} + + G5 {:priority 1.0 + :state [(in prisoner room2) + (in self room2)]} + } diff --git a/src/test/java/edu/rpi/rair/GoalTrackerTest.java b/src/test/java/edu/rpi/rair/GoalTrackerTest.java index fb352dc..9b7dd60 100644 --- a/src/test/java/edu/rpi/rair/GoalTrackerTest.java +++ b/src/test/java/edu/rpi/rair/GoalTrackerTest.java @@ -35,7 +35,6 @@ public class GoalTrackerTest { 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 diff --git a/target/classes/edu/rpi/rair/goal_tracking_tests.clj b/target/classes/edu/rpi/rair/goal_tracking_tests.clj index 1cbd653..7a7e6eb 100644 --- a/target/classes/edu/rpi/rair/goal_tracking_tests.clj +++ b/target/classes/edu/rpi/rair/goal_tracking_tests.clj @@ -1,62 +1,84 @@ {:definitions - {:name "Moving Between Rooms" - :background [(not (= room1 room2)) - (forall [?x] (iff (Locked ?x) (not (Open ?x)))) - (forall [?x ?y ?z] (if (and (In ?x ?y) (not (= ?z ?y))) - (not (In ?x ?z))))] - :start [(In self room1) - (In commander room2) - (In prisoner room1) - (Open (door room2)) - (not (Open (door room1)))] - :goal [] - :actions - [(define-action open-door [?room] - {:preconditions [(not (Open (door ?room)))] - :additions [(Open (door ?room))] - :deletions [(not (Open (door ?room)))]}) + {:name "demo 1" + :background [ + (forall [?x ?room1 ?room2] + (if (not (= ?room1 ?room2)) + (if (in ?x ?room1) (not (in ?x ?room2))) )) + (not (= room1 room2)) + (not (= prisoner commander)) + (not (= self prisoner)) + (not (= self commander)) + (person prisoner) + (person commander) + ] + :start [(in self room1) + (in commander room2) + (in prisoner room1) + (open (door room2)) + (not (open (door room1)))] - (define-action move-thing-from-to [?thing ?room1 ?room2] - {:preconditions [(not (= ?room1 ?room2)) - (In ?thing ?room1) - (Open (door ?room1)) - (Open (door ?room2))] + :goal [] - :additions [(In ?thing ?room2)] - :deletions [(In ?thing ?room1) - (In self ?room1)]}) - (define-action accompany-from-to [?thing ?room1 ?room2] - {:preconditions [(not (= ?room1 ?room2)) - (In self ?room1) - (In ?thing ?room1) - (Open (door ?room1)) - (Open (door ?room2))] + :actions + [(define-action open-door [?room] + {:preconditions [(not (open (door ?room)))] + :additions [(open (door ?room))] + :deletions [(not (open (door ?room)))]}) - :additions [(In ?thing ?room2) - (In ?self ?room2)] - :deletions [(In ?thing ?room1) - (In self ?room1)]}) - (define-action interrogate [?A ?B] - {:preconditions [(In ?room ?A) - (In ?room ?B)] - :additions [(Interrogates ?A ?B)] - :deletions [(In ?thing ?room1) - (In self ?room1)]})] + (define-action accompany [?person ?room1 ?room2] + {:preconditions [(not (= ?room1 ?room2)) + (in ?person ?room1) + (in self ?room1) + (open (door ?room1)) + (open (door ?room2))] + + :additions [(in ?person ?room2) + (in self ?room2)] + + :deletions [(in ?person ?room1) + (in self ?room1)]}) + + (define-action move [?person ?room2 ?room1] + {:preconditions [(not (= ?room1 ?room2)) + (in ?person ?room2) + (open (door ?room1)) + (open (door ?room2))] + + :additions [(in ?person ?room1)] + + :deletions [(in ?person ?room2)]}) + + (define-action get-interrogated [?room] + {:preconditions [(in commander ?room) + (in prisoner ?room)] + + :additions [(interrogates commander prisoner)] + + :deletions []}) + ] } - :goals {G1 {:priority 1 - :state [(not (Open (door room1)))]} + :goals {G1 {:priority 1.0 + :state [(not (open (door room1)))]} - G2 {:priority 1 - :state [(In prisoner room1)]} + G2 {:priority 1.0 + :state [(in prisoner room1)]} - G3 {:priority 1 + G3 {:priority 1.0 :state [(forall [?room] - (if (In prisoner ?room) - (In self ?room)))] - } + (if (in prisoner ?room) + (in self ?room)))]} + + G4 {:priority 2.0 + + :state [(interrogates commander prisoner)]} + + G5 {:priority 1.0 + :state [(in prisoner room2) + (in self room2)]} + } diff --git a/target/classes/edu/rpi/rair/utils/GoalTrackingProblem.class b/target/classes/edu/rpi/rair/utils/GoalTrackingProblem.class index d5e015a..c83e72b 100644 Binary files a/target/classes/edu/rpi/rair/utils/GoalTrackingProblem.class and b/target/classes/edu/rpi/rair/utils/GoalTrackingProblem.class differ diff --git a/target/classes/edu/rpi/rair/utils/RunDemo.class b/target/classes/edu/rpi/rair/utils/RunDemo.class index 70a58f9..688e49e 100644 Binary files a/target/classes/edu/rpi/rair/utils/RunDemo.class and b/target/classes/edu/rpi/rair/utils/RunDemo.class differ diff --git a/target/test-classes/edu/rpi/rair/GoalTrackerTest.class b/target/test-classes/edu/rpi/rair/GoalTrackerTest.class index f18090a..18ce583 100644 Binary files a/target/test-classes/edu/rpi/rair/GoalTrackerTest.class and b/target/test-classes/edu/rpi/rair/GoalTrackerTest.class differ