diff --git a/.idea/libraries/Maven__com_diogonunes_JCDP_2_0_1.xml b/.idea/libraries/Maven__com_diogonunes_JCDP_2_0_1.xml new file mode 100644 index 0000000..574defc --- /dev/null +++ b/.idea/libraries/Maven__com_diogonunes_JCDP_2_0_1.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Maven__org_fusesource_jansi_jansi_1_11.xml b/.idea/libraries/Maven__org_fusesource_jansi_jansi_1_11.xml new file mode 100644 index 0000000..2ab51a7 --- /dev/null +++ b/.idea/libraries/Maven__org_fusesource_jansi_jansi_1_11.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 0000000..35eb1dd --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/pom.xml b/pom.xml index d7191e8..ebdc119 100644 --- a/pom.xml +++ b/pom.xml @@ -24,6 +24,11 @@ test + + com.diogonunes + JCDP + 2.0.1 + us.bpsm edn-java diff --git a/snark-20120808r02/snark-interface.lisp b/snark-20120808r02/snark-interface.lisp index 8771762..6149fb0 100644 --- a/snark-20120808r02/snark-interface.lisp +++ b/snark-20120808r02/snark-interface.lisp @@ -40,6 +40,7 @@ (snark:prove-supported t) (snark:use-hyperresolution t) (snark:use-paramodulation t) + (snark:allow-skolem-symbols-in-answers nil)) (defun row-formula (name)) @@ -135,6 +136,9 @@ ""))))) +(defun get-answer-string (proof) + (string-downcase (princ-to-string (@! (rest (snark:answer proof)))))) + (defun prove-from-axioms-and-get-answers (all-axioms f vars &key (time-limit 5) @@ -157,9 +161,39 @@ (let ((proof (snark:prove (!@ f) :answer (!@ (cons 'ans vars)) ))) (if (equalp :PROOF-FOUND proof) - (string-downcase (princ-to-string (@! (rest (snark:answer proof) )))) + (get-answer-string proof) ""))))) +(defun prove-from-axioms-and-get-multiple-answers (all-axioms f vars + &key + (time-limit 5) + (verbose nil) + sortal-setup-fn) + (let ((axioms (remove-duplicates all-axioms :test #'equalp))) + (setup-snark :time-limit time-limit :verbose verbose) + (if sortal-setup-fn (funcall sortal-setup-fn)) + (let* ((n-a (make-hash-table :test #'equalp)) + (a-n (make-hash-table :test #'equalp))) + (mapcar (lambda (axiom) + (let ((name (gensym))) + (setf (gethash (princ-to-string axiom) a-n) name) + (setf (gethash (princ-to-string name) n-a) axiom))) axioms) + (mapcar (lambda (axiom) + (snark::assert axiom :name (gethash (princ-to-string axiom) a-n) + )) + (mapcar #'!@ axioms)) + + (let ((proof (snark:prove (!@ f) :answer (!@ (cons 'ans vars)) ))) + + (if (equalp :PROOF-FOUND proof) + (princ-to-string (cons (get-answer-string proof) (call))) + ""))))) + +(defun call () + (let ((proof (snark:closure))) + (if (equalp :PROOF-FOUND proof) + (cons (get-answer-string proof) (call)) + ()))) (defun proved? (ans) (first ans)) (defun used-premises (ans) (second ans)) diff --git a/src/main/java/edu/rpi/rair/DepthFirstPlanner.java b/src/main/java/edu/rpi/rair/DepthFirstPlanner.java index 97c4639..fa32817 100644 --- a/src/main/java/edu/rpi/rair/DepthFirstPlanner.java +++ b/src/main/java/edu/rpi/rair/DepthFirstPlanner.java @@ -14,10 +14,26 @@ import java.util.stream.Collectors; public class DepthFirstPlanner implements Planner { + private static final int MAX_DEPTH = 4; + + @Override public Optional> plan(Set background, Set actions, State start, State goal) { + return planInternal(Sets.newSet(), 0, background, actions, start, goal); + + + } + + + + private Optional> planInternal(Set> history, int currentDepth, Set background, Set 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> nextStateActionPair = Operations.apply(background, action, start); + Optional>> nextStateActionPairs = Operations.apply(background, action, start); - if (nextStateActionPair.isPresent()) { + if (nextStateActionPairs.isPresent()) { - Optional> planOpt = plan(background, actions, nextStateActionPair.get().first(), goal); + for (Pair stateActionPair : nextStateActionPairs.get()) { - if (planOpt.isPresent()) { - atleastOnePlanFound = true; - Set nextPlans = planOpt.get(); - State nextSate = nextStateActionPair.get().first(); - Action instantiatedAction = nextStateActionPair.get().second(); + Optional> planOpt = planInternal(history, currentDepth+1, background, actions, stateActionPair.first(), goal); - Set 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 nextPlans = planOpt.get(); + + State nextSate = stateActionPair.first(); + Action instantiatedAction = stateActionPair.second(); + + Set 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 { } + } diff --git a/src/main/java/edu/rpi/rair/Goal.java b/src/main/java/edu/rpi/rair/Goal.java index f8cdd50..bc4c36e 100644 --- a/src/main/java/edu/rpi/rair/Goal.java +++ b/src/main/java/edu/rpi/rair/Goal.java @@ -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 + '\'' + '}'; } diff --git a/src/main/java/edu/rpi/rair/GoalTracker.java b/src/main/java/edu/rpi/rair/GoalTracker.java index 8bd84a5..e979c8f 100644 --- a/src/main/java/edu/rpi/rair/GoalTracker.java +++ b/src/main/java/edu/rpi/rair/GoalTracker.java @@ -14,6 +14,9 @@ import java.util.Set; public class GoalTracker { + + + private final Set background; private State currentState; private final Set currentGoals; @@ -32,6 +35,7 @@ public class GoalTracker { public boolean adoptGoal(Goal goal) { + Optional> possiblePlans = planner.plan(background, actions, currentState, goal.getGoalState()); if (!possiblePlans.isPresent()) { diff --git a/src/main/java/edu/rpi/rair/Operations.java b/src/main/java/edu/rpi/rair/Operations.java index 326d4a7..81575cf 100644 --- a/src/main/java/edu/rpi/rair/Operations.java +++ b/src/main/java/edu/rpi/rair/Operations.java @@ -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> proveAndGetBindings(Set givens, Formula goal, List variables){ - return prover.proveAndGetBindings(givens, goal, variables); + Future>> future = new FutureTask<>(()->{ + return prover.proveAndGetBindings(givens, goal, variables); + + + }); + + Optional> answer; + + try{ + + answer = future.get(1, TimeUnit.SECONDS); + } catch (InterruptedException | ExecutionException | TimeoutException e) { + answer = Optional.empty(); + } + + return answer; } - public static Optional> apply(Set background, Action action, State state){ - Prover prover = new SnarkWrapper(); + public static synchronized Optional>> proveAndGetMultipleBindings(Set givens, Formula goal, List variables){ + + return prover.proveAndGetMultipleBindings(givens, goal, variables); + + /* Future>>> future = new FutureTask<>(()-> prover.proveAndGetMultipleBindings(givens, goal, variables)); + + Optional>> answer; + + try{ + + answer = future.get(50, TimeUnit.SECONDS); + } catch (InterruptedException | ExecutionException | TimeoutException e ) { + answer = Optional.empty(); + } + return answer; + +*/ + } + + public static Optional>> apply(Set background, Action action, State state){ + Set givens = Sets.union(background, state.getFormulae()); - Optional> bingdingsOpt = proveAndGetBindings(givens, action.getPrecondition(), action.openVars()); + Optional>> bindingsOpt = proveAndGetMultipleBindings(givens, action.getPrecondition(), action.openVars()); State newState; - if(!bingdingsOpt.isPresent()){ + if(!bindingsOpt.isPresent()){ return Optional.empty(); } + + Set> nexts = Sets.newSet(); + for(Map binding: bindingsOpt.get()){ + + if(binding.values().stream().anyMatch(x-> x instanceof Variable)){ + + continue; + } + + Set instantiatedDeletions = action.instantiateDeletions(binding); + + Set formulaeToRemove = state.getFormulae().stream(). + filter(f-> instantiatedDeletions.stream().anyMatch(d-> equivalent(background, f,d))).collect(Collectors.toSet()); + Set 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 emptyBinding = CollectionUtils.newMap(); + Set instantiatedDeletions = action.instantiateDeletions(emptyBinding); + + Set formulaeToRemove = state.getFormulae().stream(). + filter(f-> instantiatedDeletions.stream().anyMatch(d-> equivalent(background, f,d))).collect(Collectors.toSet()); + + Set 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 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 background, State state, State goal){ diff --git a/src/main/java/edu/rpi/rair/utils/GoalTrackingProblem.java b/src/main/java/edu/rpi/rair/utils/GoalTrackingProblem.java new file mode 100644 index 0000000..94104b7 --- /dev/null +++ b/src/main/java/edu/rpi/rair/utils/GoalTrackingProblem.java @@ -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 goals; + private final Map 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 goals) { + this.planningProblem = planningProblem; + this.goals = goals; + this.goalNameMap = CollectionUtils.newMap(); + + for(Goal g: goals){ + goalNameMap.put(g.getName(), g); + } + + + } + + public static List readFromFile(InputStream inputStream) throws Reader.ParsingException { + + Parseable parseable = Parsers.newParseable(new InputStreamReader(inputStream)); + Parser parser = Parsers.newParser(Parsers.defaultConfiguration()); + + List goalTrackingProblems = CollectionUtils.newEmptyList(); + + Object nextValue = parser.nextValue(parseable); + + Set 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 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 getGoals() { + return goals; + } + + public Goal getGoalNamed(String goalName) { + return goalNameMap.get(goalName); + } +} diff --git a/src/main/java/edu/rpi/rair/utils/PlanningProblem.java b/src/main/java/edu/rpi/rair/utils/PlanningProblem.java index b598cd2..d806dbd 100644 --- a/src/main/java/edu/rpi/rair/utils/PlanningProblem.java +++ b/src/main/java/edu/rpi/rair/utils/PlanningProblem.java @@ -81,52 +81,7 @@ public class PlanningProblem { while (!nextValue.equals(Token.END_OF_INPUT)) { - Map planningProblemSpec = (Map) nextValue; - - Set background = readFrom((List) planningProblemSpec.get(BACKGROUND)); - Set start = readFrom((List) planningProblemSpec.get(START)); - Set goal = readFrom((List) planningProblemSpec.get(GOAL)); - - List actionDefinitions = (List) planningProblemSpec.get(ACTION); - - String name = planningProblemSpec.get(NAME).toString(); - Set actions = readActionsFrom(actionDefinitions); - Map 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> expectedActions = plans.stream().map(plan->{ - - List instantActionList = (List) plan; - - List 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 background = readFrom((List) planningProblemSpec.get(BACKGROUND)); + Set start = readFrom((List) planningProblemSpec.get(START)); + + + Set goal = readFrom((List) planningProblemSpec.get(GOAL)); + + List actionDefinitions = (List) planningProblemSpec.get(ACTION); + + String name = planningProblemSpec.get(NAME).toString(); + Set actions = readActionsFrom(actionDefinitions); + Map 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> expectedActions = plans.stream().map(plan->{ + + List instantActionList = (List) plan; + + List 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 actionMap, Object instantiatedActionSpec) throws Reader.ParsingException { @@ -222,7 +227,7 @@ public class PlanningProblem { } - private static Set readFrom(List objects) throws Reader.ParsingException { + public static Set readFrom(List objects) throws Reader.ParsingException { Set formulae = objects.stream().map(x -> { try { diff --git a/src/main/java/edu/rpi/rair/utils/RunDemo.java b/src/main/java/edu/rpi/rair/utils/RunDemo.java new file mode 100644 index 0000000..082cb1c --- /dev/null +++ b/src/main/java/edu/rpi/rair/utils/RunDemo.java @@ -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 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")); + + + + } + +} diff --git a/src/main/resources/edu/rpi/rair/completeness_problems.clj b/src/main/resources/edu/rpi/rair/completeness_problems.clj index cc8d55a..b006894 100644 --- a/src/main/resources/edu/rpi/rair/completeness_problems.clj +++ b/src/main/resources/edu/rpi/rair/completeness_problems.clj @@ -1,12 +1,12 @@ -{:name "test 1" - :background [P] - :start [Q] - :goal [R] +{:name "test 1" + :background [p] + :start [q] + :goal [r] :actions - [(define-action a1 () - {:preconditions [(or Q R)] - :additions [R] - :deletions [Q]})] + [(define-action a1 () + {:preconditions [(or q r)] + :additions [r] + :deletions [q]})] :expected-plans ([a1]) } @@ -15,13 +15,13 @@ {:name "simple killing" :background [] - :start [(forall ?x (Alive ?x))] - :goal [(forall ?x (Dead ?x))] + :start [(forall ?x (alive ?x))] + :goal [(forall ?x (dead ?x))] :actions [(define-action kill () - {:preconditions [(Alive ?x)] - :additions [(Dead ?x)] - :deletions [(Alive ?x)]})] + {:preconditions [(alive ?x)] + :additions [(dead ?x)] + :deletions [(alive ?x)]})] :expected-plans ([kill]) @@ -111,62 +111,74 @@ [drink eat work])} -{:name "bidding problem" - :background [] - :start [(bid 0)] - :goal [(bid 5)] + + +{:name "demo 1" + :background [ + (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)))] + :goal [(interrogates commander prisoner)] :actions - [(define-action post-new-bid (?number) - {:preconditions [(bid ?number)] - :additions [(bid ($$sum 1 ?number))] - :deletions [(bid ?number)]})] + [(define-action open-door [?room] + {:preconditions [(not (open (door ?room)))] + :additions [(open (door ?room))] + :deletions [(not (open (door ?room)))]}) - :expected-plans ([(post-new-bid 0) - (post-new-bid 1) - (post-new-bid 2) - (post-new-bid 3) - (post-new-bid 4)])} -{:name "Moving Between Rooms" - :background [ (not (= room1 room2))] - :start [(In self room1) - (In commander room2) - (In prisoner room1) - (Open (door room2)) - (not (Open (door room1))) ] - :goal [(In prisoner room2)] - :actions - [(define-action open-door [?room] - {:preconditions [(not (Open (door ?room)))] - :additions [(Open (door ?room))] - :deletions [(not (Open (door ?room)))]}) + (define-action accompany[?person ?room1 ?room2] + {:preconditions [(not (= ?room1 ?room2)) + (in ?person ?room1) + (in self ?room1) + (open (door ?room1)) + (open (door ?room2))] - (define-action move-thing-from-to [?thing ?room1 ?room2] - {:preconditions [(not (= ?room1 ?room2)) - (In ?thing ?room1) - (Open (door ?room1)) - (Open (door ?room2))] + :additions [(in ?person ?room2) + (in self ?room2)] + :deletions [(in ?person ?room1) + (in self ?room1)]}) - :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))] + (define-action request-move [?person ?room2 ?room1] + {:preconditions [(not (= ?room1 ?room2)) + (in ?person ?room2) + (not (= ?person prisoner)) + (open (door ?room1)) + (open (door ?room2))] - :additions [(In ?thing ?room2) - (In ?self ?room2)] - :deletions [(In ?thing ?room1) - (In self ?room1)]})] + :additions [(in ?person ?room1)] + :deletions [(in ?person ?room2)]}) - :expected-plans ([(open-door room1) - (accompany-from-to prisoner room1 room2)] + (define-action get-interrogated [?room] + {:preconditions [(in commander ?room) + (in prisoner ?room)] + + :additions [(interrogates commander prisoner)] + :deletions []}) + ] + + :expected-plans ( [(open-door room1) - (move-thing-from-to prisoner room1 room2)]) + (request-move commander room2 room1) + (get-interrogated room1) + ] + + [(open-door room1) + (accompany prisoner room1 room2) + (get-interrogated room2) + ] + + ) } + diff --git a/src/main/resources/edu/rpi/rair/debug.clj b/src/main/resources/edu/rpi/rair/debug.clj index 8b13789..09ad17e 100644 --- a/src/main/resources/edu/rpi/rair/debug.clj +++ b/src/main/resources/edu/rpi/rair/debug.clj @@ -1 +1,15 @@ +{:name "bidding problem" + :background [] + :start [(bid 0)] + :goal [(bid 5)] + :actions + [(define-action post-new-bid (?number) + {:preconditions [(bid ?number)] + :additions [(bid ($$sum 1 ?number))] + :deletions [(bid ?number)]})] + :expected-plans ([(post-new-bid 0) + (post-new-bid 1) + (post-new-bid 2) + (post-new-bid 3) + (post-new-bid 4)])} 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 1715e5b..1cbd653 100644 --- a/src/main/resources/edu/rpi/rair/goal_tracking_tests.clj +++ b/src/main/resources/edu/rpi/rair/goal_tracking_tests.clj @@ -1,30 +1,63 @@ -{:name "Sim" - :background [] - :start [(In self room1) - (In commander room2) - (In prisoner room1) - (Open (door room2)) - (not (Open (door room1))) ] +{: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)))]}) - :actions [(define-action open-door [?room] - {:preconditions [(not (Open (door ?room)))] - :additions [(Open (door ?room))] - :deletions [(not (Open (door ?room)))]}) + (define-action move-thing-from-to [?thing ?room1 ?room2] + {:preconditions [(not (= ?room1 ?room2)) + (In ?thing ?room1) + (Open (door ?room1)) + (Open (door ?room2))] + :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))] + :additions [(In ?thing ?room2) + (In ?self ?room2)] + :deletions [(In ?thing ?room1) + (In self ?room1)]}) - (define-action accompany-from-to [?thing ?room1 ?room2] - {:preconditions [(In self ?room1) - (In ?thing ?room1) - (Open (door ?room1)) - (Open (door ?room2))] + (define-action interrogate [?A ?B] + {:preconditions [(In ?room ?A) + (In ?room ?B)] - :additions [(In ?thing ?room2) - (In ?self ?room2)] - :deletions [(In ?thing ?room1) - (In self ?room1)]})] + :additions [(Interrogates ?A ?B)] + :deletions [(In ?thing ?room1) + (In self ?room1)]})] +} - :expected-plans ([(open-door room1) - (accompany-from-to prisoner room1 room2)]) + :goals {G1 {:priority 1 + :state [(not (Open (door room1)))]} + + G2 {:priority 1 + :state [(In prisoner room1)]} + + G3 {:priority 1 + :state [(forall [?room] + (if (In prisoner ?room) + (In self ?room)))] + } + + } } \ No newline at end of file diff --git a/src/test/java/edu/rpi/rair/DepthFirstPlannerTest.java b/src/test/java/edu/rpi/rair/DepthFirstPlannerTest.java index 51ec9e5..1586553 100644 --- a/src/test/java/edu/rpi/rair/DepthFirstPlannerTest.java +++ b/src/test/java/edu/rpi/rair/DepthFirstPlannerTest.java @@ -33,8 +33,8 @@ public class DepthFirstPlannerTest { Planner depthFirstPlanner = new DepthFirstPlanner(); - PlanningProblem planningProblem = planningProblemList.get(2); - System.out.println(depthFirstPlanner.plan(planningProblem.getBackground(), planningProblem.getActions(), planningProblem.getStart(), planningProblem.getGoal())); + PlanningProblem planningProblem = planningProblemList.get(5); + depthFirstPlanner.plan(planningProblem.getBackground(), planningProblem.getActions(), planningProblem.getStart(), planningProblem.getGoal()).get().forEach(System.out::println); } @DataProvider diff --git a/src/test/java/edu/rpi/rair/GoalTrackerTest.java b/src/test/java/edu/rpi/rair/GoalTrackerTest.java new file mode 100644 index 0000000..fb352dc --- /dev/null +++ b/src/test/java/edu/rpi/rair/GoalTrackerTest.java @@ -0,0 +1,56 @@ +package edu.rpi.rair; + +import com.diogonunes.jcdp.color.ColoredPrinter; +import com.diogonunes.jcdp.color.api.Ansi; +import com.naveensundarg.shadow.prover.utils.Reader; +import edu.rpi.rair.utils.GoalTrackingProblem; + +import java.util.List; + +import static org.testng.Assert.*; + +/** + * Created by naveensundarg on 1/15/17. + */ +public class GoalTrackerTest { + + + public static void main(String[] args) throws Reader.ParsingException { + + List 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")); + + + + } +} \ No newline at end of file diff --git a/target/classes/edu/rpi/rair/debug.clj b/target/classes/edu/rpi/rair/debug.clj index 8b13789..09ad17e 100644 --- a/target/classes/edu/rpi/rair/debug.clj +++ b/target/classes/edu/rpi/rair/debug.clj @@ -1 +1,15 @@ +{:name "bidding problem" + :background [] + :start [(bid 0)] + :goal [(bid 5)] + :actions + [(define-action post-new-bid (?number) + {:preconditions [(bid ?number)] + :additions [(bid ($$sum 1 ?number))] + :deletions [(bid ?number)]})] + :expected-plans ([(post-new-bid 0) + (post-new-bid 1) + (post-new-bid 2) + (post-new-bid 3) + (post-new-bid 4)])} diff --git a/target/classes/edu/rpi/rair/goal_tracking_tests.clj b/target/classes/edu/rpi/rair/goal_tracking_tests.clj index 1715e5b..1cbd653 100644 --- a/target/classes/edu/rpi/rair/goal_tracking_tests.clj +++ b/target/classes/edu/rpi/rair/goal_tracking_tests.clj @@ -1,30 +1,63 @@ -{:name "Sim" - :background [] - :start [(In self room1) - (In commander room2) - (In prisoner room1) - (Open (door room2)) - (not (Open (door room1))) ] +{: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)))]}) - :actions [(define-action open-door [?room] - {:preconditions [(not (Open (door ?room)))] - :additions [(Open (door ?room))] - :deletions [(not (Open (door ?room)))]}) + (define-action move-thing-from-to [?thing ?room1 ?room2] + {:preconditions [(not (= ?room1 ?room2)) + (In ?thing ?room1) + (Open (door ?room1)) + (Open (door ?room2))] + :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))] + :additions [(In ?thing ?room2) + (In ?self ?room2)] + :deletions [(In ?thing ?room1) + (In self ?room1)]}) - (define-action accompany-from-to [?thing ?room1 ?room2] - {:preconditions [(In self ?room1) - (In ?thing ?room1) - (Open (door ?room1)) - (Open (door ?room2))] + (define-action interrogate [?A ?B] + {:preconditions [(In ?room ?A) + (In ?room ?B)] - :additions [(In ?thing ?room2) - (In ?self ?room2)] - :deletions [(In ?thing ?room1) - (In self ?room1)]})] + :additions [(Interrogates ?A ?B)] + :deletions [(In ?thing ?room1) + (In self ?room1)]})] +} - :expected-plans ([(open-door room1) - (accompany-from-to prisoner room1 room2)]) + :goals {G1 {:priority 1 + :state [(not (Open (door room1)))]} + + G2 {:priority 1 + :state [(In prisoner room1)]} + + G3 {:priority 1 + :state [(forall [?room] + (if (In prisoner ?room) + (In self ?room)))] + } + + } } \ No newline at end of file diff --git a/target/classes/edu/rpi/rair/utils/GoalTrackingProblem.class b/target/classes/edu/rpi/rair/utils/GoalTrackingProblem.class new file mode 100644 index 0000000..d5e015a Binary files /dev/null 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 new file mode 100644 index 0000000..70a58f9 Binary files /dev/null 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 new file mode 100644 index 0000000..f18090a Binary files /dev/null and b/target/test-classes/edu/rpi/rair/GoalTrackerTest.class differ