From c9201bc0b211be07910c6a5ea18ec6ae7c2a27ae Mon Sep 17 00:00:00 2001 From: Naveen Sundar Govindarajulu Date: Sun, 15 Jan 2017 22:13:40 -0500 Subject: [PATCH] working version of the muri demo --- src/main/java/edu/rpi/rair/Goal.java | 25 ++-- src/main/java/edu/rpi/rair/GoalTracker.java | 28 ++-- .../rpi/rair/utils/GoalTrackingProblem.java | 2 +- src/main/java/edu/rpi/rair/utils/RunDemo.java | 126 ++++++++++++++---- .../edu/rpi/rair/completeness_problems.clj | 27 ++-- .../edu/rpi/rair/goal_tracking_tests.clj | 118 +++++++++------- .../java/edu/rpi/rair/GoalTrackerTest.java | 1 - .../edu/rpi/rair/goal_tracking_tests.clj | 118 +++++++++------- .../rpi/rair/utils/GoalTrackingProblem.class | Bin 5158 -> 5109 bytes .../classes/edu/rpi/rair/utils/RunDemo.class | Bin 2789 -> 6385 bytes .../edu/rpi/rair/GoalTrackerTest.class | Bin 2801 -> 2775 bytes 11 files changed, 290 insertions(+), 155 deletions(-) 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 d5e015a0c9f665806eea345d80d24b89e7744a1f..c83e72b46e4d01613f657cd8c5de5bcd43b255ad 100644 GIT binary patch delta 1676 zcmZvdc~sO@6vscmf#ET~d2C|`h1B$@EGmtaZZ8y#KtZXrD&urK7)G4~}Hyk{jnm^vX@4b7!_xry0&dlnpqnVN2e{bFn z^yiq(DJ=Gp&DCbP#^ze;jdz`&>$$s5+VEIs=rt%BZMk0WrzZ{ZG}&xmV?6!inHbMAicO7&mB(&WG%H#Z zo1MQrTdlmN%`wNU9$OS!725<^;)I}uonJS*q_QSlQC_XsVNvAFh{HJ`9w^C<@`66S^Ghk~^= z;j&<1s8Tb8p_+qyCNI={&KH_t=HyH2EIRxvwr75MP1OR;SM1V!%><$Hjd6!F)FRmp zEen;;4dzwU&MGU>e9IxtndUO_I8H&hx<>OIhZWyze&9#VPyDR;#c<1TR(di{)Qn)H zg}=CDPPjbWCg!i2BOGf3Euzc)?yAF%@dVz=s~P+4t>MNC$9 zo>QN&!pd`Y#AP{S6W315me~MBz%)U;fawDkXNd1%fb69e?fb!`8)f7!-RR+3d8cdT zNn+z9R(MKou2YmW$r|OXP0Ebq$xUx!=|>9roFyJ&M>9sO@l0*Y^-OgSXN#}fPX@@z zIdakoPpeFEtm0fnfuc|`7XBc!jqQ0dzT+q&hFl@P2rtQ!b$AQT*yJ2*o3k)^s5Q%J zN$y`XC?QR+r$-B&JUmO!W_k@yO7o^AHIvaPAIm%0_W77ThS>015=rdRnFoRWr|A_<%$YLr8Em#WoGREUMMbg+bOHt z&eCIap-Qk~9vRBXfs{3)M#Y;G$*o9`fG_uSF*_9 zRZCjFIOfwm(6^bKCOQUAc5Qkf=-O_9ey;7&C_$E6BjA2ZItxx0nd6gW`nyS`h}?U) eim77LMgGq6Lq8?XCpvAHN%rxM{7JkU=lcgXqDMmj delta 1756 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

2$%w-D3wiRlFE^i`k2Kn@q(jm?tx zqU21O&xF2(b5)f5Bla7ZkGuI}{12(uz|ZkZ_795l#Il_Yc$obv_K&cS>}(L-qF3|~ S*N3=IBKa_7eFPuHUH=Dp)4Q+$ delta 977 zcmZvbNl#Qk6otR)e(ihRJRjQHV1pvG6Cw(2J0XbRgtOv=qJXW9h$53XfM`2`^H>{~ z#>D7C7i!WNP5c4I#9v|J%EXOJ<1KKZ#*6jq zxao3>n8Ihu+uU)v%e{Y@3(da3-};1E707E%ohs8$gW0;k$@g(zS30}jd~#kWRs8#Q zo{mgd>9={Ho4wik`S?1W=lyW(?%wv!zK%|vlO5A%LlxtL$y8T&U!7b|k)zAAB37fK zR98EtekC>~y;zG3K3)E?`Ftp;VuCZIDwC)r21-UyuSU0L3XU6H^q3{NJ4RqObEFDV z%v@65>2-z7XEVrW8YbIt0n>Z=MHH? zqh6fYD?3f1XqN$dWW;_M@S-q>n8$tQ^N0mJ7N4F`&I{sao!&5gu~N`InRm zU48*iL{cUmC8SBYNc?i(85T-y$uZmH#Vr=+mWa%Fn}ty>m28=;SQ0BlyIgV~mBL0Y dXvzE9%vN!~f)qz2?qHA$HBotJgIukN{sQ8Qq|yKY diff --git a/target/test-classes/edu/rpi/rair/GoalTrackerTest.class b/target/test-classes/edu/rpi/rair/GoalTrackerTest.class index f18090a4b6e6286a084141dfab471f7a7f10667a..18ce583107cc80f6eb9d3bf07fe66530ed1a0ff3 100644 GIT binary patch delta 773 zcmZva%TE(g6vlruEzESd!3csDMGGp>0#*v*1JNQ%6%l-b3MiE#mPd=VAo#)uzR{43 z(S;k`xX}%g)Wn5*FV&j;9vu z*lw`Hq`_h*jTQ#Ga@bASpvhp5lQ&!JWuF5r4n!ipAoILEm69I^v7eDDHAkai5ZZmqHqPB&2x2L&YN=+do{b+U!Dudsufr z(eT@i*+up@)3n@{LlgvXo71Bh^ zS|3^R!aKX!)7$NJzh`-dJcsi$tnj+?R%Iykx-+b-uFCUfD9W(9>p!wJf60pf$edYR zIJ0z8U>jEDbU6dE^C*7O1el_V88$I1M|j3&UQ)v=LcFDZaq7CI$wVEH9yz?GQXCqE zJf~WGI=%#5 z11~(JnUnEgJbN*oJoy`pS7wa$J9#k1e)z7ne!uT`t@T@beaZNqG5PV=yZ69)o_NV& zi^*1t8ZXabha()- zUaQ41ZI5ecvpAtMwQFgImC8wrQx=^TT_)Wor{`t{l*fpMhl2{$=KN4$6?QsZ1@2t( zoM~4@dXLRnA~xsfHR-cCPrviY)sQp5pvjO;lwq3-jM!Y%UM{01mlS2rXXSS~-1*(P zjML;To(#O`g?ME2DoOiI3Z-