Details
diff --git a/bdi-jade/src/br/ufrgs/inf/bdi4jade/core/BDIAgent.java b/bdi-jade/src/br/ufrgs/inf/bdi4jade/core/BDIAgent.java
index e367a4a..cd4b0dd 100644
--- a/bdi-jade/src/br/ufrgs/inf/bdi4jade/core/BDIAgent.java
+++ b/bdi-jade/src/br/ufrgs/inf/bdi4jade/core/BDIAgent.java
@@ -236,7 +236,7 @@ public class BDIAgent extends Agent {
* the goal to be achieved.
*/
public void addGoal(Goal goal) {
- this.addGoal(goal, null);
+ this.addGoal(null, goal, null);
}
/**
@@ -249,8 +249,37 @@ public class BDIAgent extends Agent {
* the listener to be notified.
*/
public void addGoal(Goal goal, GoalListener goalListener) {
+ this.addGoal(null, goal, goalListener);
+ }
+
+ /**
+ * Adds a new goal to this agent to be achieved.
+ *
+ * @param owner
+ * the Capability that is owner of the goal.
+ * @param goal
+ * the goal to be achieved.
+ */
+ public void addGoal(Capability owner, Goal goal) {
+ this.addGoal(owner, goal, null);
+ }
+
+ /**
+ * Adds a new goal to this agent to be achieved and adds a listener to
+ * observe its end. If this goal has a capability that owns it, only plans
+ * of this capability and its children capabilities will be considered to
+ * achieve this goal.
+ *
+ * @param owner
+ * the Capability that is owner of the goal.
+ * @param goal
+ * the goal to be achieved.
+ * @param goalListener
+ * the listener to be notified.
+ */
+ public void addGoal(Capability owner, Goal goal, GoalListener goalListener) {
synchronized (intentions) {
- Intention intention = new Intention(this, goal);
+ Intention intention = new Intention(goal, this, owner);
this.intentions.add(intention);
this.bdiInterpreter.restart();
if (goalListener != null) {
diff --git a/bdi-jade/src/br/ufrgs/inf/bdi4jade/core/Intention.java b/bdi-jade/src/br/ufrgs/inf/bdi4jade/core/Intention.java
index 029e149..f1c6649 100644
--- a/bdi-jade/src/br/ufrgs/inf/bdi4jade/core/Intention.java
+++ b/bdi-jade/src/br/ufrgs/inf/bdi4jade/core/Intention.java
@@ -61,7 +61,7 @@ public class Intention {
private final Log log;
private final BDIAgent myAgent;
private boolean noLongerDesired;
- private final Capability owner;// XXX Intention - owner (Capability)
+ private final Capability owner;
private boolean unachievable;
private boolean waiting;
@@ -74,7 +74,7 @@ public class Intention {
* @param bdiAgent
* the bdiAgent associated with this intention.
*/
- public Intention(BDIAgent bdiAgent, Goal goal) {
+ public Intention(Goal goal, BDIAgent bdiAgent) {
this(goal, bdiAgent, null);
}
@@ -198,13 +198,18 @@ public class Intention {
}
/**
- * Returns all plans from all capabilities that can achieve the goal.
+ * Returns all plans from the capabilities that can achieve the goal. If the
+ * goal is associated with a capability, only the capability and its
+ * children capabilities will be searched. Otherwise, all plan libraries
+ * will be considered.
*
* @return the set of plans that can achieve the goal.
*/
private Set<Plan> getCanAchievePlans() {
Set<Plan> plans = new HashSet<Plan>();
- getCanAchievePlans(plans, myAgent.getRootCapability());
+ Capability capability = owner == null ? myAgent.getRootCapability()
+ : owner;
+ getCanAchievePlans(plans, capability);
return plans;
}
diff --git a/bdi-jade/src/br/ufrgs/inf/bdi4jade/plan/PlanInstance.java b/bdi-jade/src/br/ufrgs/inf/bdi4jade/plan/PlanInstance.java
index 795995d..aed9e88 100644
--- a/bdi-jade/src/br/ufrgs/inf/bdi4jade/plan/PlanInstance.java
+++ b/bdi-jade/src/br/ufrgs/inf/bdi4jade/plan/PlanInstance.java
@@ -91,6 +91,49 @@ public class PlanInstance implements GoalListener {
}
/**
+ * Dispatches a goal to be achieved, using the capability (or its children
+ * capabilities) associated with the plan.
+ *
+ * @param goal
+ * the goal to be dispatched.
+ */
+ public void dispatchProtectedGoal(Goal goal) {
+ this.intention.getMyAgent().addGoal(
+ this.plan.getPlanLibrary().getCapability(), goal);
+ }
+
+ /**
+ * Dispatches a subgoal to be achieved, using the capability (or its
+ * children capabilities) associated with the plan.
+ *
+ * @param subgoal
+ * the subgoal to be dispatched.
+ */
+ public void dispatchProtectedSubgoal(Goal subgoal) {
+ this.intention.getMyAgent().addGoal(
+ this.plan.getPlanLibrary().getCapability(), subgoal);
+ synchronized (subgoals) {
+ this.subgoals.add(subgoal);
+ }
+ }
+
+ /**
+ * Dispatches a subgoal to be achieved, using the capability (or its
+ * children capabilities) associated with the plan, and registers itself as
+ * a listener to receive a notification of the end of execution of the goal.
+ *
+ * @param subgoal
+ * the subgoal to be dispatched.
+ */
+ public void dispatchProtectedSubgoalAndListen(Goal subgoal) {
+ this.intention.getMyAgent().addGoal(
+ this.plan.getPlanLibrary().getCapability(), subgoal, this);
+ synchronized (subgoals) {
+ this.subgoals.add(subgoal);
+ }
+ }
+
+ /**
* Dispatches a goal to be achieved.
*
* @param goal
diff --git a/bdi-jade-test/src/br/ufrgs/inf/bdi4jade/examples/AgentStarter.java b/bdi-jade-test/src/br/ufrgs/inf/bdi4jade/examples/AgentStarter.java
index f15384b..5d2d85c 100644
--- a/bdi-jade-test/src/br/ufrgs/inf/bdi4jade/examples/AgentStarter.java
+++ b/bdi-jade-test/src/br/ufrgs/inf/bdi4jade/examples/AgentStarter.java
@@ -38,7 +38,7 @@ import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.log4j.PropertyConfigurator;
-import br.ufrgs.inf.bdi4jade.examples.template.MyAgent;
+import br.ufrgs.inf.bdi4jade.examples.helloworld.HelloWorldAgent;
/**
* @author ingrid
@@ -50,11 +50,12 @@ public class AgentStarter {
static {
agents = new HashMap<String, Agent>();
- // agents.put(HelloWorldAgent.class.getSimpleName(), new
- // HelloWorldAgent());
+ agents.put(HelloWorldAgent.class.getSimpleName(), new HelloWorldAgent());
// agents.put(BDIAgent1.MY_NAME, new BDIAgent1());
// agents.put(BDIAgent2.MY_NAME, new BDIAgent2());
- agents.put(MyAgent.class.getSimpleName(), new MyAgent());
+ // agents.put(MyAgent.class.getSimpleName(), new MyAgent());
+ // agents.put(NestedCapabilitiesAgent.class.getSimpleName(),
+ // new NestedCapabilitiesAgent());
};
public static void main(String[] args) {
diff --git a/bdi-jade-test/src/br/ufrgs/inf/bdi4jade/examples/nestedcapabilities/NestedCapabilitiesAgent.java b/bdi-jade-test/src/br/ufrgs/inf/bdi4jade/examples/nestedcapabilities/NestedCapabilitiesAgent.java
new file mode 100644
index 0000000..e10d790
--- /dev/null
+++ b/bdi-jade-test/src/br/ufrgs/inf/bdi4jade/examples/nestedcapabilities/NestedCapabilitiesAgent.java
@@ -0,0 +1,76 @@
+/*
+ * Created on 19 Oct 2011 14:42:24
+ */
+package br.ufrgs.inf.bdi4jade.examples.nestedcapabilities;
+
+import jade.core.behaviours.Behaviour;
+import br.ufrgs.inf.bdi4jade.belief.TransientBelief;
+import br.ufrgs.inf.bdi4jade.core.BDIAgent;
+import br.ufrgs.inf.bdi4jade.core.Capability;
+import br.ufrgs.inf.bdi4jade.goal.Goal;
+import br.ufrgs.inf.bdi4jade.util.plan.SimplePlan;
+
+class ChildGoal implements Goal {
+ private static final long serialVersionUID = 7656633869373580240L;
+}
+
+class MyGoal implements Goal {
+ private static final long serialVersionUID = -5054184951317760743L;
+}
+
+public class NestedCapabilitiesAgent extends BDIAgent {
+
+ public enum Belief {
+
+ CHILD_BELIEF, MY_BELIEF, PARENT_BELIEF, SIBLING_BELIEF;
+
+ }
+
+ private static final long serialVersionUID = 2712019445290687786L;
+
+ private void addBelief(Capability capability, Belief belief) {
+ capability.getBeliefBase().addBelief(
+ new TransientBelief<String>(belief.name(), belief.name()));
+ }
+
+ private void addPlan(Capability capability, Class<? extends Goal> goal,
+ Class<? extends Behaviour> planBody) {
+ capability.getPlanLibrary().addPlan(new SimplePlan(goal, planBody));
+ }
+
+ protected void init() {
+ addBelief(getRootCapability(), Belief.PARENT_BELIEF);
+ addPlan(getRootCapability(), ParentGoal.class, SuccessPlanBody.class);
+
+ Capability capability = new Capability();
+ addBelief(capability, Belief.MY_BELIEF);
+ addPlan(capability, TestGoal.class, TestPlanBody.class);
+ addPlan(capability, MyGoal.class, SuccessPlanBody.class);
+
+ Capability sibling = new Capability();
+ addBelief(sibling, Belief.SIBLING_BELIEF);
+ addPlan(sibling, SiblingGoal.class, SuccessPlanBody.class);
+
+ Capability child = new Capability();
+ addBelief(child, Belief.CHILD_BELIEF);
+ addPlan(child, ChildGoal.class, SuccessPlanBody.class);
+
+ getRootCapability().addChild(capability);
+ getRootCapability().addChild(sibling);
+ capability.addChild(child);
+
+ addGoal(new TestGoal());
+ }
+}
+
+class ParentGoal implements Goal {
+ private static final long serialVersionUID = 1371943799864265143L;
+}
+
+class SiblingGoal implements Goal {
+ private static final long serialVersionUID = 7250708504253085098L;
+}
+
+class TestGoal implements Goal {
+ private static final long serialVersionUID = -5054184951317760743L;
+}
diff --git a/bdi-jade-test/src/br/ufrgs/inf/bdi4jade/examples/nestedcapabilities/SuccessPlanBody.java b/bdi-jade-test/src/br/ufrgs/inf/bdi4jade/examples/nestedcapabilities/SuccessPlanBody.java
new file mode 100644
index 0000000..0f29afa
--- /dev/null
+++ b/bdi-jade-test/src/br/ufrgs/inf/bdi4jade/examples/nestedcapabilities/SuccessPlanBody.java
@@ -0,0 +1,32 @@
+package br.ufrgs.inf.bdi4jade.examples.nestedcapabilities;
+
+import jade.core.behaviours.OneShotBehaviour;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import br.ufrgs.inf.bdi4jade.plan.PlanBody;
+import br.ufrgs.inf.bdi4jade.plan.PlanInstance;
+import br.ufrgs.inf.bdi4jade.plan.PlanInstance.EndState;
+
+public class SuccessPlanBody extends OneShotBehaviour implements PlanBody {
+
+ private static final long serialVersionUID = -9039447524062487795L;
+
+ private EndState endState;
+ private Log log;
+
+ public void action() {
+ log.info(this.getClass().getSimpleName() + " executed.");
+ this.endState = EndState.SUCCESSFUL;
+ }
+
+ public EndState getEndState() {
+ return endState;
+ }
+
+ public void init(PlanInstance planInstance) {
+ this.log = LogFactory.getLog(this.getClass());
+ this.endState = null;
+ }
+}
diff --git a/bdi-jade-test/src/br/ufrgs/inf/bdi4jade/examples/nestedcapabilities/TestPlanBody.java b/bdi-jade-test/src/br/ufrgs/inf/bdi4jade/examples/nestedcapabilities/TestPlanBody.java
new file mode 100644
index 0000000..58ef87f
--- /dev/null
+++ b/bdi-jade-test/src/br/ufrgs/inf/bdi4jade/examples/nestedcapabilities/TestPlanBody.java
@@ -0,0 +1,144 @@
+package br.ufrgs.inf.bdi4jade.examples.nestedcapabilities;
+
+import jade.core.behaviours.Behaviour;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import br.ufrgs.inf.bdi4jade.event.GoalFinishedEvent;
+import br.ufrgs.inf.bdi4jade.examples.nestedcapabilities.NestedCapabilitiesAgent.Belief;
+import br.ufrgs.inf.bdi4jade.goal.GoalStatus;
+import br.ufrgs.inf.bdi4jade.plan.PlanBody;
+import br.ufrgs.inf.bdi4jade.plan.PlanInstance;
+import br.ufrgs.inf.bdi4jade.plan.PlanInstance.EndState;
+
+public class TestPlanBody extends Behaviour implements PlanBody {
+
+ enum TestStep {
+ BELIEF, CHILD_GOAL, COMPLETED, MY_GOAL, PARENT_GOAL, PARENT_PROTECTED_GOAL, SIBLING_GOAL, SIBLING_PROTECTED_GOAL;
+ }
+
+ private static final long serialVersionUID = -9039447524062487795L;
+
+ private PlanInstance instance;
+ private Log log;
+ private TestStep step;
+
+ public void action() {
+ switch (step) {
+ case BELIEF:
+ log.info("Testing beliefs...");
+ log.info("These should be not null:");
+ printBelief(Belief.MY_BELIEF);
+ printBelief(Belief.PARENT_BELIEF);
+ log.info("These should be null:");
+ printBelief(Belief.SIBLING_BELIEF);
+ printBelief(Belief.CHILD_BELIEF);
+
+ log.info("Testing plans...");
+ instance.dispatchProtectedSubgoalAndListen(new MyGoal());
+ this.step = TestStep.MY_GOAL;
+ break;
+ case MY_GOAL:
+ GoalFinishedEvent goalEvent = instance.getGoalEvent();
+ if (goalEvent == null) {
+ return;
+ } else {
+ printGoal(goalEvent, true);
+ instance.dispatchProtectedSubgoalAndListen(new ChildGoal());
+ }
+ this.step = TestStep.CHILD_GOAL;
+ break;
+ case CHILD_GOAL:
+ goalEvent = instance.getGoalEvent();
+ if (goalEvent == null) {
+ return;
+ } else {
+ printGoal(goalEvent, true);
+ instance.dispatchSubgoalAndListen(new ParentGoal());
+ }
+
+ this.step = TestStep.PARENT_GOAL;
+ break;
+ case PARENT_GOAL:
+ goalEvent = instance.getGoalEvent();
+ if (goalEvent == null) {
+ return;
+ } else {
+ printGoal(goalEvent, true);
+ instance.dispatchSubgoalAndListen(new SiblingGoal());
+ }
+
+ this.step = TestStep.SIBLING_GOAL;
+ break;
+ case SIBLING_GOAL:
+ goalEvent = instance.getGoalEvent();
+ if (goalEvent == null) {
+ return;
+ } else {
+ printGoal(goalEvent, true);
+ instance.dispatchProtectedSubgoalAndListen(new ParentGoal());
+ }
+
+ this.step = TestStep.PARENT_PROTECTED_GOAL;
+ break;
+ case PARENT_PROTECTED_GOAL:
+ goalEvent = instance.getGoalEvent();
+ if (goalEvent == null) {
+ return;
+ } else {
+ printGoal(goalEvent, false);
+ instance.dispatchProtectedSubgoalAndListen(new SiblingGoal());
+ }
+
+ this.step = TestStep.SIBLING_PROTECTED_GOAL;
+ break;
+ case SIBLING_PROTECTED_GOAL:
+ goalEvent = instance.getGoalEvent();
+ if (goalEvent == null) {
+ return;
+ } else {
+ printGoal(goalEvent, false);
+ }
+
+ this.step = TestStep.COMPLETED;
+ break;
+ case COMPLETED:
+ break;
+ }
+ }
+
+ @Override
+ public boolean done() {
+ return getEndState() != null;
+ }
+
+ public EndState getEndState() {
+ return TestStep.COMPLETED.equals(step) ? EndState.SUCCESSFUL : null;
+ }
+
+ public void init(PlanInstance planInstance) {
+ this.log = LogFactory.getLog(this.getClass());
+ this.instance = planInstance;
+ this.step = TestStep.BELIEF;
+ }
+
+ private void printBelief(Belief belief) {
+ log.info(belief + ": "
+ + instance.getBeliefBase().getBelief(belief.name()));
+
+ }
+
+ private void printGoal(GoalFinishedEvent goalEvent, boolean achievedExpected) {
+ if (GoalStatus.ACHIEVED.equals(goalEvent.getStatus())) {
+ log.debug("Goal " + goalEvent.getGoal().getClass().getSimpleName()
+ + " completed - " + (achievedExpected ? "" : "un")
+ + "expected result");
+ } else {
+ log.debug("A goal has failed: "
+ + goalEvent.getGoal().getClass().getSimpleName() + " - "
+ + (achievedExpected ? "un" : "") + "expected result");
+ }
+
+ }
+}