bdi4jade
Changes
bdi-jade/src/bdi4jade/core/AbstractBDIAgent.java 741(+741 -0)
bdi-jade/src/bdi4jade/core/BDIAgent.java 669(+29 -640)
Details
bdi-jade/src/bdi4jade/core/AbstractBDIAgent.java 741(+741 -0)
diff --git a/bdi-jade/src/bdi4jade/core/AbstractBDIAgent.java b/bdi-jade/src/bdi4jade/core/AbstractBDIAgent.java
new file mode 100644
index 0000000..d6304ca
--- /dev/null
+++ b/bdi-jade/src/bdi4jade/core/AbstractBDIAgent.java
@@ -0,0 +1,741 @@
+//----------------------------------------------------------------------------
+// Copyright (C) 2011 Ingrid Nunes
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// To contact the authors:
+// http://inf.ufrgs.br/~ingridnunes/bdi4jade/
+//
+//----------------------------------------------------------------------------
+
+package bdi4jade.core;
+
+import jade.core.Agent;
+import jade.core.behaviours.CyclicBehaviour;
+import jade.lang.acl.ACLMessage;
+import jade.proto.states.MsgReceiver;
+
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import bdi4jade.annotation.GoalOwner;
+import bdi4jade.belief.Belief;
+import bdi4jade.core.GoalUpdateSet.GoalDescription;
+import bdi4jade.event.GoalEvent;
+import bdi4jade.event.GoalListener;
+import bdi4jade.goal.Goal;
+import bdi4jade.goal.GoalStatus;
+import bdi4jade.goal.Softgoal;
+import bdi4jade.message.BDIAgentMsgReceiver;
+import bdi4jade.plan.Plan;
+import bdi4jade.util.ReflectionUtils;
+
+/**
+ * This class is an abstract implementation of the {@link BDIAgent} interface.
+ * It is an extension of {@link Agent}. It also has a set of {@link Capability}
+ * - an agent is an aggregation of capabilities, and a {@link MsgReceiver}
+ * behavior to receive all messages that the agent current plans can process.
+ *
+ * @author Ingrid Nunes
+ */
+public abstract class AbstractBDIAgent extends Agent implements BDIAgent {
+
+ /**
+ * This class is a {@link CyclicBehaviour} that runs during all the
+ * {@link BDIAgent} life in order to provide the reasoning engine.
+ *
+ * @author Ingrid Nunes
+ */
+ class BDIInterpreter extends CyclicBehaviour {
+
+ private static final long serialVersionUID = -6991759791322598475L;
+
+ private BDIInterpreter(AbstractBDIAgent bdiAgent) {
+ super(bdiAgent);
+ }
+
+ /**
+ * This method is a variation of the BDI-interpreter cycle of the BDI
+ * architecture. It first reviews the beliefs of this agent, by invoking
+ * the {@link BDIAgent#reviewBeliefs()} method.
+ *
+ * After it removes from the intention set the ones that are finished,
+ * i.e. associated with goals with status achieved, no longer desired or
+ * unachievable, and notifies goal listeners about this event. This is
+ * performed using the {@link #processIntentions(Collection)} method.
+ *
+ * Then, it generate a an updated set of goals, dropping existing ones
+ * that are no longer desired and also creating new ones. This updated
+ * set of goals is given by the
+ * {@link BDIAgent#generateGoals(GoalUpdateSet, Map)} method.
+ *
+ * Finally, from the set of current goals, they are now filtered, by
+ * invoking the {@link BDIAgent#filter(Set, Map)} method, to select the
+ * current agent intentions. The non-selected goals will be set to wait
+ * ({@link Intention#doWait()}) and the selected ones will be tried to
+ * be achieved ({@link Intention#tryToAchive()}).
+ *
+ * @see jade.core.behaviours.Behaviour#action()
+ */
+ @Override
+ public void action() {
+ log.trace("Beginning BDI-interpreter cycle.");
+
+ log.trace("Reviewing beliefs.");
+ reviewBeliefs();
+
+ synchronized (allIntentions) {
+ // Removing finished goals and generate appropriate goal events
+ GoalUpdateSet agentGoalUpdateSet = processIntentions(agentIntentions);
+ Map<Capability, GoalUpdateSet> capabilityGoalUpdateSets = new HashMap<>();
+ for (Capability capability : capabilities) {
+ GoalUpdateSet capabilityGoalUpdateSet = processIntentions(capability
+ .getIntentions());
+ capabilityGoalUpdateSets.put(capability,
+ capabilityGoalUpdateSet);
+ }
+
+ // Generating new goals and choosing goals to drop
+ generateGoals(agentGoalUpdateSet, capabilityGoalUpdateSets);
+
+ // Adding generated goals
+ for (GoalDescription goal : agentGoalUpdateSet
+ .getGeneratedGoals()) {
+ Intention intention = addIntention(goal.getDispatcher(),
+ goal.getGoal(), null);
+ if (intention != null)
+ agentGoalUpdateSet.addIntention(intention);
+ }
+ for (GoalUpdateSet goalUpdateSet : capabilityGoalUpdateSets
+ .values()) {
+ for (GoalDescription goal : goalUpdateSet
+ .getGeneratedGoals()) {
+ Intention intention = addIntention(
+ goal.getDispatcher(), goal.getGoal(), null);
+ if (intention != null)
+ goalUpdateSet.addIntention(intention);
+ }
+ }
+
+ // Removing dropped goals
+ for (GoalDescription goal : agentGoalUpdateSet
+ .getDroppedGoals()) {
+ goal.getIntention().noLongerDesire();
+ fireGoalEvent(goal.getIntention());
+ agentIntentions.remove(goal.getIntention());
+ allIntentions.remove(goal.getGoal());
+ agentGoalUpdateSet.removeIntention(goal);
+ }
+ for (GoalUpdateSet goalUpdateSet : capabilityGoalUpdateSets
+ .values()) {
+ for (GoalDescription goal : goalUpdateSet.getDroppedGoals()) {
+ goal.getIntention().noLongerDesire();
+ fireGoalEvent(goal.getIntention());
+ goal.getDispatcher().removeIntention(
+ goal.getIntention());
+ allIntentions.remove(goal.getGoal());
+ goalUpdateSet.removeIntention(goal);
+ }
+ }
+
+ // Filtering options
+ Map<Capability, Set<GoalDescription>> capabilityGoals = new HashMap<>();
+ for (Capability capability : capabilityGoalUpdateSets.keySet()) {
+ capabilityGoals.put(capability, capabilityGoalUpdateSets
+ .get(capability).getCurrentGoals());
+ }
+ Set<Goal> selectedGoals = filter(
+ agentGoalUpdateSet.getCurrentGoals(), capabilityGoals);
+
+ log.trace("Selected goals to be intentions: "
+ + selectedGoals.size());
+ for (Intention intention : allIntentions.values()) {
+ if (selectedGoals.contains(intention.getGoal())) {
+ intention.tryToAchive();
+ } else {
+ intention.doWait();
+ }
+ }
+
+ if (allIntentions.isEmpty()) {
+ log.trace("No goals or intentions: blocking cycle.");
+ this.block();
+ }
+ }
+
+ log.trace("BDI-interpreter cycle finished.");
+ }
+
+ /**
+ * Processes all intentions of the given collection. Intentions
+ * associated with goals that finished are removed and goal listeners (
+ * {@link GoalListener}) are notified. Goal listeners are also notified
+ * if a plan failed while trying to achieve a goal (intentions with
+ * {@link GoalStatus#PLAN_FAILED}).
+ *
+ * @param intentions
+ * the collection of intentions to be processed.
+ * @return the {@link GoalUpdateSet} with current goals initialized with
+ * current intentions.
+ */
+ private GoalUpdateSet processIntentions(Collection<Intention> intentions) {
+ GoalUpdateSet goalUpdateSet = new GoalUpdateSet();
+ Iterator<Intention> it = intentions.iterator();
+ while (it.hasNext()) {
+ Intention intention = it.next();
+ GoalStatus status = intention.getStatus();
+ if (status.isFinished()) {
+ fireGoalEvent(intention);
+ it.remove();
+ allIntentions.remove(intention.getGoal());
+ } else {
+ if (GoalStatus.PLAN_FAILED.equals(status)) {
+ fireGoalEvent(intention);
+ }
+ goalUpdateSet.addIntention(intention);
+ }
+ }
+ return goalUpdateSet;
+ }
+
+ }
+
+ private static final long serialVersionUID = -841774495336214256L;
+
+ private final Collection<Intention> agentIntentions;
+ private final Set<Capability> aggregatedCapabilities;
+ private final Map<Goal, Intention> allIntentions;
+ private final BDIInterpreter bdiInterpreter;
+ private Set<Capability> capabilities;
+ protected final List<GoalListener> goalListeners;
+ protected final Log log;
+ private Map<Class<? extends Capability>, Set<Capability>> restrictedAccessOwnersMap;
+ private final Set<Softgoal> softgoals;
+
+ /**
+ * Default constructor.
+ */
+ public AbstractBDIAgent() {
+ this.log = LogFactory.getLog(this.getClass());
+ this.bdiInterpreter = new BDIInterpreter(this);
+ this.capabilities = new HashSet<>();
+ this.restrictedAccessOwnersMap = new HashMap<>();
+ this.allIntentions = new HashMap<>();
+ this.aggregatedCapabilities = new HashSet<>();
+ this.agentIntentions = new LinkedList<>();
+ this.softgoals = new HashSet<>();
+ this.goalListeners = new LinkedList<>();
+ }
+
+ /**
+ * Adds a capability to this agent.
+ *
+ * @param capability
+ * capability to be added.
+ */
+ void addCapability(Capability capability) {
+ synchronized (aggregatedCapabilities) {
+ this.aggregatedCapabilities.add(capability);
+ resetAllCapabilities();
+ computeGoalOwnersMap();
+ }
+ }
+
+ /**
+ * @see bdi4jade.core.BDIAgent#addGoal(bdi4jade.core.Capability,
+ * bdi4jade.goal.Goal)
+ */
+ @Override
+ public final void addGoal(Capability dispatcher, Goal goal) {
+ addIntention(dispatcher, goal, null);
+ }
+
+ /**
+ * @see bdi4jade.core.BDIAgent#addGoal(bdi4jade.core.Capability,
+ * bdi4jade.goal.Goal, bdi4jade.event.GoalListener)
+ */
+ @Override
+ public final void addGoal(Capability dispatcher, Goal goal,
+ GoalListener goalListener) {
+ addIntention(dispatcher, goal, goalListener);
+ }
+
+ /**
+ * @see bdi4jade.core.BDIAgent#addGoal(bdi4jade.goal.Goal)
+ */
+ @Override
+ public final void addGoal(Goal goal) {
+ addIntention(null, goal, null);
+ }
+
+ /**
+ * @see bdi4jade.core.BDIAgent#addGoal(bdi4jade.goal.Goal,
+ * bdi4jade.event.GoalListener)
+ */
+ @Override
+ public final void addGoal(Goal goal, GoalListener goalListener) {
+ addIntention(null, goal, goalListener);
+ }
+
+ /**
+ * @see bdi4jade.core.BDIAgent#addGoalListener(bdi4jade.event.GoalListener)
+ */
+ @Override
+ public final void addGoalListener(GoalListener goalListener) {
+ synchronized (goalListeners) {
+ goalListeners.add(goalListener);
+ }
+ }
+
+ /**
+ * Adds a new goal to this agent to be achieved by creating an intention. It
+ * also may add a listener to observe events related to this goal.
+ *
+ * @param dispatcher
+ * the capability that dispatched this goal.
+ * @param goal
+ * the goal to be achieved.
+ * @param goalListener
+ * the listener to be notified.
+ */
+ private final Intention addIntention(Capability dispatcher, Goal goal,
+ GoalListener goalListener) {
+ Intention intention = null;
+ try {
+ intention = new Intention(goal, this, dispatcher);
+ } catch (IllegalAccessException exc) {
+ log.error(exc);
+ return null;
+ }
+
+ synchronized (allIntentions) {
+ this.allIntentions.put(goal, intention);
+ if (dispatcher == null) {
+ agentIntentions.add(intention);
+ } else {
+ dispatcher.addIntention(intention);
+ }
+ this.bdiInterpreter.restart();
+ if (goalListener != null) {
+ intention.addGoalListener(goalListener);
+ }
+ fireGoalEvent(new GoalEvent(goal));
+ return intention;
+ }
+ }
+
+ /**
+ * @see bdi4jade.core.BDIAgent#addSoftgoal(bdi4jade.goal.Softgoal)
+ */
+ @Override
+ public final void addSoftgoal(Softgoal softgoal) {
+ synchronized (softgoals) {
+ this.softgoals.add(softgoal);
+ }
+ }
+
+ /**
+ * @see bdi4jade.core.BDIAgent#canHandle(jade.lang.acl.ACLMessage)
+ */
+ @Override
+ public boolean canHandle(ACLMessage msg) {
+ synchronized (aggregatedCapabilities) {
+ for (Capability capability : aggregatedCapabilities) {
+ if (capability.canHandle(msg)) {
+ return true;
+ }
+ }
+ return false;
+ }
+ }
+
+ private final void computeGoalOwnersMap() {
+ this.restrictedAccessOwnersMap = new HashMap<>();
+ for (Capability capability : aggregatedCapabilities) {
+ ReflectionUtils.addGoalOwner(restrictedAccessOwnersMap, capability);
+ }
+ }
+
+ /**
+ * @see bdi4jade.core.BDIAgent#dropGoal(bdi4jade.goal.Goal)
+ */
+ @Override
+ public final void dropGoal(Goal goal) {
+ synchronized (allIntentions) {
+ Intention intention = allIntentions.get(goal);
+ if (intention != null) {
+ intention.noLongerDesire();
+ }
+ }
+ }
+
+ /**
+ * @see bdi4jade.core.BDIAgent#dropSoftoal(bdi4jade.goal.Softgoal)
+ */
+ @Override
+ public final void dropSoftoal(Softgoal softgoal) {
+ synchronized (softgoals) {
+ this.softgoals.remove(softgoal);
+ }
+ }
+
+ /**
+ * This method is responsible for selecting a set of goals that must be
+ * tried to be achieved (intentions) from the set of goals. Its default
+ * implementation selects all agent goals (those not dispatched within the
+ * scope of a capability) to be achieved, and requests each of its
+ * capabilities to filter their goals. Subclasses may override this method
+ * to customize this deliberation function.
+ *
+ * @param agentGoals
+ * the set of agent goals, which are goals not dispatched within
+ * the scope of a capability.
+ * @param capabilityGoals
+ * the map from capabilities to their set of goals.
+ *
+ * @return the list of selected goals, which will become intentions.
+ */
+ protected Set<Goal> filter(Set<GoalDescription> agentGoals,
+ Map<Capability, Set<GoalDescription>> capabilityGoals) {
+ Set<Goal> selectedGoals = new HashSet<>();
+ for (GoalDescription goalDescription : agentGoals) {
+ selectedGoals.add(goalDescription.getGoal());
+ }
+ for (Capability capability : capabilityGoals.keySet()) {
+ selectedGoals.addAll(capability.filter(capabilityGoals
+ .get(capability)));
+ }
+ return selectedGoals;
+ }
+
+ /**
+ * Notifies all listeners, if any, about a goal event.
+ *
+ * @param goalEvent
+ * the event to notify.
+ */
+ private final void fireGoalEvent(GoalEvent goalEvent) {
+ synchronized (goalListeners) {
+ for (GoalListener goalListener : goalListeners) {
+ goalListener.goalPerformed(goalEvent);
+ }
+ }
+ }
+
+ /**
+ * Creates a goal event given an intention, and notifies all listeners, if
+ * any, about a goal event.
+ *
+ * @param intention
+ * the intention used to create the goal event.
+ */
+ private final void fireGoalEvent(Intention intention) {
+ Goal goal = intention.getGoal();
+ GoalStatus status = intention.getStatus();
+ log.debug("Goal: " + goal.getClass().getSimpleName() + " (" + status
+ + ") - " + goal);
+
+ GoalEvent goalEvent = new GoalEvent(goal, status);
+ synchronized (goalListeners) {
+ for (GoalListener goalListener : goalListeners) {
+ goalListener.goalPerformed(goalEvent);
+ }
+ for (GoalListener goalListener : intention.getGoalListeners()) {
+ goalListener.goalPerformed(goalEvent);
+ }
+ }
+ }
+
+ /**
+ * This method is responsible for generating new goals or dropping existing
+ * ones. Its default implementation requests each of its capabilities to
+ * generate or drop goals. Subclasses may override this method to customize
+ * this options generation function.
+ *
+ * @param agentGoalUpdateSet
+ * the {@link GoalUpdateSet} that contains the set of agent
+ * current goals. It has also a set of dropped goals and
+ * generated goals, which are used as outputs of this method.
+ * @param capabilityGoalUpdateSets
+ * the map from capabilities to their goal update set.
+ */
+ protected void generateGoals(GoalUpdateSet agentGoalUpdateSet,
+ Map<Capability, GoalUpdateSet> capabilityGoalUpdateSets) {
+ for (Capability capability : capabilityGoalUpdateSets.keySet()) {
+ capability.generateGoals(capabilityGoalUpdateSets.get(capability));
+ }
+ }
+
+ /**
+ * Returns the root capability of this agent.
+ *
+ * @return the rootCapability
+ */
+ protected Set<Capability> getAggregatedCapabilities() {
+ synchronized (aggregatedCapabilities) {
+ return aggregatedCapabilities;
+ }
+ }
+
+ /**
+ * @see bdi4jade.core.BDIAgent#getAllBeliefs()
+ */
+ @Override
+ public final Collection<Belief<?>> getAllBeliefs() {
+ synchronized (aggregatedCapabilities) {
+ Collection<Belief<?>> beliefs = new LinkedList<Belief<?>>();
+ for (Capability capability : capabilities) {
+ beliefs.addAll(capability.getBeliefBase().getBeliefs());
+ }
+ return beliefs;
+ }
+ }
+
+ /**
+ * Returns all capabilities that are part of this agent. This included all
+ * capabilities composed or associated with other capabilities.
+ *
+ * @return the capabilities.
+ */
+ protected Collection<Capability> getAllCapabilities() {
+ synchronized (aggregatedCapabilities) {
+ return capabilities;
+ }
+ }
+
+ /**
+ * @see bdi4jade.core.BDIAgent#getAllGoals()
+ */
+ @Override
+ public final Set<Goal> getAllGoals() {
+ synchronized (allIntentions) {
+ return allIntentions.keySet();
+ }
+ }
+
+ /**
+ * @see bdi4jade.core.BDIAgent#getAllSoftgoals()
+ */
+ @Override
+ public final Set<Softgoal> getAllSoftgoals() {
+ synchronized (softgoals) {
+ return this.softgoals;
+ }
+ }
+
+ /**
+ * @see bdi4jade.core.BDIAgent#getGoalListeners()
+ */
+ @Override
+ public final List<GoalListener> getGoalListeners() {
+ return goalListeners;
+ }
+
+ /**
+ * Returns the capability instances that owns a dispatched goal, considering
+ * the aggregated capabilities of this agent.
+ *
+ * If this method returns an empty set, it means that this agent cannot add
+ * a goal without the scope of a dispatcher that has access to it.
+ *
+ * @param owner
+ * the annotation with the goal owner.
+ * @return the capability instances related to this capability that owns the
+ * goal, or an empty set if the agent cannot add this goal.
+ */
+ protected final Set<Capability> getGoalOwner(GoalOwner owner) {
+ Set<Capability> restrictedAccessOwners = restrictedAccessOwnersMap
+ .get(owner.capability());
+ return restrictedAccessOwners == null ? new HashSet<Capability>()
+ : restrictedAccessOwners;
+ }
+
+ /**
+ * @see bdi4jade.core.BDIAgent#getIntentions()
+ */
+ @Override
+ public final Set<Intention> getIntentions() {
+ synchronized (allIntentions) {
+ Set<Intention> activeIntentions = new HashSet<Intention>();
+ for (Intention intention : activeIntentions) {
+ if (!GoalStatus.WAITING.equals(intention.getStatus()))
+ activeIntentions.add(intention);
+ }
+ return activeIntentions;
+ }
+ }
+
+ /**
+ * This method initializes the BDI agent. It is invoked by the
+ * {@link #setup()} method. This is an empty method that should be overriden
+ * by subclasses.
+ */
+ protected void init() {
+
+ }
+
+ /**
+ * Removes a capability from this agent.
+ *
+ * @param capability
+ * capability to be removed.
+ *
+ * @return true if the capability exists and was removed, false otherwise.
+ */
+ boolean removeCapability(Capability capability) {
+ synchronized (aggregatedCapabilities) {
+ boolean removed = this.aggregatedCapabilities.remove(capability);
+ if (removed) {
+ resetAllCapabilities();
+ computeGoalOwnersMap();
+ }
+ return removed;
+ }
+ }
+
+ /**
+ * @see bdi4jade.core.BDIAgent#removeGoalListener(bdi4jade.event.GoalListener)
+ */
+ @Override
+ public final void removeGoalListener(GoalListener goalListener) {
+ synchronized (goalListeners) {
+ goalListeners.remove(goalListener);
+ }
+ }
+
+ final void resetAllCapabilities() {
+ synchronized (aggregatedCapabilities) {
+ Set<Capability> allCapabilities = new HashSet<>();
+ Set<Capability> capabilitiesToBeProcessed = new HashSet<>(
+ aggregatedCapabilities);
+
+ while (!capabilitiesToBeProcessed.isEmpty()) {
+ Capability current = capabilitiesToBeProcessed.iterator()
+ .next();
+ capabilitiesToBeProcessed.remove(current);
+ allCapabilities.add(current);
+ for (Capability part : current.getPartCapabilities()) {
+ if (!allCapabilities.contains(part))
+ capabilitiesToBeProcessed.add(part);
+ }
+ for (Capability target : current.getAssociatedCapabilities()) {
+ if (!allCapabilities.contains(target))
+ capabilitiesToBeProcessed.add(target);
+ }
+ }
+
+ Set<Capability> removedCapabilities = new HashSet<>(capabilities);
+ removedCapabilities.removeAll(allCapabilities);
+ for (Capability capability : removedCapabilities) {
+ capability.setMyAgent(null);
+ }
+
+ Set<Capability> addedCapabilities = new HashSet<>(allCapabilities);
+ addedCapabilities.removeAll(capabilities);
+ for (Capability capability : addedCapabilities) {
+ if (capability.getMyAgent() != null) {
+ throw new IllegalArgumentException(
+ "Capability already binded to another agent: "
+ + capability.getFullId());
+ }
+ capability.setMyAgent(this);
+ }
+
+ this.capabilities = allCapabilities;
+ log.debug("Capabilities: " + this.capabilities);
+ }
+ }
+
+ /**
+ * This method is responsible for reviewing beliefs from this agent. Its
+ * default implementation requests each of its capabilities to review their
+ * individual set of beliefs. Subclasses may override this method to
+ * customize belief revision.
+ */
+ protected void reviewBeliefs() {
+ for (Capability capability : capabilities) {
+ capability.reviewBeliefs();
+ }
+ }
+
+ /**
+ * This method is responsible for selecting plans to achieve a goals of this
+ * agent. Its default implementation requests each of its capabilities to
+ * select one of its plans, and this method selects one of them, randomly.
+ * Subclasses may override this method to customize plan selection.
+ *
+ * @param goal
+ * the goal to be achieved.
+ * @param capabilityPlans
+ * the set of candidate plans of each capability, as a map.
+ */
+ protected Plan selectPlan(Goal goal,
+ Map<Capability, Set<Plan>> capabilityPlans) {
+ Set<Plan> preselectedPlans = new HashSet<>();
+ for (Capability capability : capabilityPlans.keySet()) {
+ Plan preselectedPlan = capability.selectPlan(goal,
+ capabilityPlans.get(capability));
+ if (preselectedPlan != null) {
+ preselectedPlans.add(preselectedPlan);
+ }
+ }
+
+ if (preselectedPlans.isEmpty()) {
+ return null;
+ } else {
+ return preselectedPlans.iterator().next();
+ }
+ }
+
+ /**
+ * Initializes the BDI agent. It adds the behavior to handle message
+ * received and can be processed by capabilities and the
+ * {@link BDIInterpreter} behavior as well. It invokes the {@link #init()}
+ * method, so that customized initializations can be perfomed by subclasses.
+ *
+ * @see jade.core.Agent#setup()
+ */
+ @Override
+ protected final void setup() {
+ this.addBehaviour(new BDIAgentMsgReceiver(this));
+ this.addBehaviour(bdiInterpreter);
+ init();
+ }
+
+ /**
+ * Removes all capabilities of this agent, before it stops its execution.
+ *
+ * @see jade.core.Agent#takeDown()
+ */
+ @Override
+ protected void takeDown() {
+ synchronized (aggregatedCapabilities) {
+ Iterator<Capability> iterator = aggregatedCapabilities.iterator();
+ while (iterator.hasNext()) {
+ removeCapability(iterator.next());
+ }
+ }
+ }
+
+}
bdi-jade/src/bdi4jade/core/BDIAgent.java 669(+29 -640)
diff --git a/bdi-jade/src/bdi4jade/core/BDIAgent.java b/bdi-jade/src/bdi4jade/core/BDIAgent.java
index a5a59a0..54497f8 100644
--- a/bdi-jade/src/bdi4jade/core/BDIAgent.java
+++ b/bdi-jade/src/bdi4jade/core/BDIAgent.java
@@ -22,284 +22,26 @@
package bdi4jade.core;
-import jade.core.Agent;
-import jade.core.behaviours.CyclicBehaviour;
-import jade.proto.states.MsgReceiver;
+import jade.lang.acl.ACLMessage;
import java.util.Collection;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.LinkedList;
import java.util.List;
-import java.util.Map;
import java.util.Set;
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-
-import bdi4jade.annotation.GoalOwner;
import bdi4jade.belief.Belief;
-import bdi4jade.core.GoalUpdateSet.GoalDescription;
-import bdi4jade.event.GoalEvent;
import bdi4jade.event.GoalListener;
import bdi4jade.goal.Goal;
-import bdi4jade.goal.GoalStatus;
import bdi4jade.goal.Softgoal;
-import bdi4jade.message.BDIAgentMsgReceiver;
-import bdi4jade.plan.Plan;
-import bdi4jade.util.ReflectionUtils;
/**
- * This class is an extension of {@link Agent} that has a current set of goals,
- * which can be selected to become intentions, that is, to tried to be achieved
- * by means of the selection and execution of plans. It also have a set of
- * {@link Capability} - an agent is an aggregation of capabilities. It has a
- * behavior that runs the BDI-interpreter. This agent also have a
- * {@link MsgReceiver} behavior to receive all messages that the agent current
- * plans can process.
+ * This interfaces represents a BDIAgent that has a current set of goals, which
+ * can be selected to become intentions, that is, to tried to be achieved by
+ * means of the selection and execution of plans. It has a behavior that runs
+ * the BDI-interpreter.
*
* @author Ingrid Nunes
*/
-public class BDIAgent extends Agent {
-
- /**
- * This class is a {@link CyclicBehaviour} that runs during all the
- * {@link BDIAgent} life in order to provide the reasoning engine.
- *
- * @author Ingrid Nunes
- */
- class BDIInterpreter extends CyclicBehaviour {
-
- private static final long serialVersionUID = -6991759791322598475L;
-
- private BDIInterpreter(BDIAgent bdiAgent) {
- super(bdiAgent);
- }
-
- /**
- * This method is a variation of the BDI-interpreter cycle of the BDI
- * architecture. It first reviews the beliefs of this agent, by invoking
- * the {@link BDIAgent#reviewBeliefs()} method.
- *
- * After it removes from the intention set the ones that are finished,
- * i.e. associated with goals with status achieved, no longer desired or
- * unachievable, and notifies goal listeners about this event. This is
- * performed using the {@link #processIntentions(Collection)} method.
- *
- * Then, it generate a an updated set of goals, dropping existing ones
- * that are no longer desired and also creating new ones. This updated
- * set of goals is given by the
- * {@link BDIAgent#generateGoals(GoalUpdateSet, Map)} method.
- *
- * Finally, from the set of current goals, they are now filtered, by
- * invoking the {@link BDIAgent#filter(Set, Map)} method, to select the
- * current agent intentions. The non-selected goals will be set to wait
- * ({@link Intention#doWait()}) and the selected ones will be tried to
- * be achieved ({@link Intention#tryToAchive()}).
- *
- * @see jade.core.behaviours.Behaviour#action()
- */
- @Override
- public void action() {
- log.trace("Beginning BDI-interpreter cycle.");
-
- log.trace("Reviewing beliefs.");
- reviewBeliefs();
-
- synchronized (allIntentions) {
- // Removing finished goals and generate appropriate goal events
- GoalUpdateSet agentGoalUpdateSet = processIntentions(agentIntentions);
- Map<Capability, GoalUpdateSet> capabilityGoalUpdateSets = new HashMap<>();
- for (Capability capability : capabilities) {
- GoalUpdateSet capabilityGoalUpdateSet = processIntentions(capability
- .getIntentions());
- capabilityGoalUpdateSets.put(capability,
- capabilityGoalUpdateSet);
- }
-
- // Generating new goals and choosing goals to drop
- generateGoals(agentGoalUpdateSet, capabilityGoalUpdateSets);
-
- // Adding generated goals
- for (GoalDescription goal : agentGoalUpdateSet
- .getGeneratedGoals()) {
- Intention intention = addIntention(goal.getDispatcher(),
- goal.getGoal(), null);
- if (intention != null)
- agentGoalUpdateSet.addIntention(intention);
- }
- for (GoalUpdateSet goalUpdateSet : capabilityGoalUpdateSets
- .values()) {
- for (GoalDescription goal : goalUpdateSet
- .getGeneratedGoals()) {
- Intention intention = addIntention(
- goal.getDispatcher(), goal.getGoal(), null);
- if (intention != null)
- goalUpdateSet.addIntention(intention);
- }
- }
-
- // Removing dropped goals
- for (GoalDescription goal : agentGoalUpdateSet
- .getDroppedGoals()) {
- goal.getIntention().noLongerDesire();
- fireGoalEvent(goal.getIntention());
- agentIntentions.remove(goal.getIntention());
- allIntentions.remove(goal.getGoal());
- agentGoalUpdateSet.removeIntention(goal);
- }
- for (GoalUpdateSet goalUpdateSet : capabilityGoalUpdateSets
- .values()) {
- for (GoalDescription goal : goalUpdateSet.getDroppedGoals()) {
- goal.getIntention().noLongerDesire();
- fireGoalEvent(goal.getIntention());
- goal.getDispatcher().removeIntention(
- goal.getIntention());
- allIntentions.remove(goal.getGoal());
- goalUpdateSet.removeIntention(goal);
- }
- }
-
- // Filtering options
- Map<Capability, Set<GoalDescription>> capabilityGoals = new HashMap<>();
- for (Capability capability : capabilityGoalUpdateSets.keySet()) {
- capabilityGoals.put(capability, capabilityGoalUpdateSets
- .get(capability).getCurrentGoals());
- }
- Set<GoalDescription> selectedGoals = filter(
- agentGoalUpdateSet.getCurrentGoals(), capabilityGoals);
-
- log.trace("Selected goals to be intentions: "
- + selectedGoals.size());
- for (Intention intention : allIntentions.values()) {
- if (selectedGoals.contains(intention.getGoal())) {
- intention.tryToAchive();
- } else {
- intention.doWait();
- }
- }
-
- if (allIntentions.isEmpty()) {
- log.trace("No goals or intentions: blocking cycle.");
- this.block();
- }
- }
-
- log.trace("BDI-interpreter cycle finished.");
- }
-
- /**
- * Processes all intentions of the given collection. Intentions
- * associated with goals that finished are removed and goal listeners (
- * {@link GoalListener}) are notified. Goal listeners are also notified
- * if a plan failed while trying to achieve a goal (intentions with
- * {@link GoalStatus#PLAN_FAILED}).
- *
- * @param intentions
- * the collection of intentions to be processed.
- * @return the {@link GoalUpdateSet} with current goals initialized with
- * current intentions.
- */
- private GoalUpdateSet processIntentions(Collection<Intention> intentions) {
- GoalUpdateSet goalUpdateSet = new GoalUpdateSet();
- Iterator<Intention> it = intentions.iterator();
- while (it.hasNext()) {
- Intention intention = it.next();
- GoalStatus status = intention.getStatus();
- if (status.isFinished()) {
- fireGoalEvent(intention);
- it.remove();
- allIntentions.remove(intention.getGoal());
- } else {
- if (GoalStatus.PLAN_FAILED.equals(status)) {
- fireGoalEvent(intention);
- }
- goalUpdateSet.addIntention(intention);
- }
- }
- return goalUpdateSet;
- }
-
- }
-
- private static final long serialVersionUID = -841774495336214256L;
-
- private final Collection<Intention> agentIntentions;
- private final Set<Capability> aggregatedCapabilities;
- private final Map<Goal, Intention> allIntentions;
- private final BDIInterpreter bdiInterpreter;
- private Set<Capability> capabilities;
- protected final List<GoalListener> goalListeners;
- protected final Log log;
- private Map<Class<? extends Capability>, Set<Capability>> restrictedAccessOwnersMap;
- private final Set<Softgoal> softgoals;
-
- /**
- * Default constructor.
- */
- public BDIAgent() {
- this.log = LogFactory.getLog(this.getClass());
- this.bdiInterpreter = new BDIInterpreter(this);
- this.capabilities = new HashSet<>();
- this.restrictedAccessOwnersMap = new HashMap<>();
- this.allIntentions = new HashMap<>();
- this.aggregatedCapabilities = new HashSet<>();
- this.agentIntentions = new LinkedList<>();
- this.softgoals = new HashSet<>();
- this.goalListeners = new LinkedList<>();
- }
-
- /**
- * Creates a new BDIAgent with a capability.
- *
- * @param capability
- * the capability to be added to the agent.
- */
- public BDIAgent(Capability capability) {
- this();
- this.addCapability(capability);
- }
-
- /**
- * Creates a new BDIAgent with a set of capabilities.
- *
- * @param capabilities
- * the capabilities to be added to the agent.
- */
- public BDIAgent(Capability[] capabilities) {
- this();
- for (Capability capability : capabilities) {
- this.addCapability(capability);
- }
- }
-
- /**
- * Creates a new BDIAgent with a set of capabilities.
- *
- * @param capabilities
- * the capabilities to be added to the agent.
- */
- public BDIAgent(Collection<Capability> capabilities) {
- this();
- for (Capability capability : capabilities) {
- this.addCapability(capability);
- }
- }
-
- /**
- * Adds a capability to this agent.
- *
- * @param capability
- * capability to be added.
- */
- public final void addCapability(Capability capability) {
- synchronized (aggregatedCapabilities) {
- this.aggregatedCapabilities.add(capability);
- resetAllCapabilities();
- computeGoalOwnersMap();
- }
- }
+public interface BDIAgent {
/**
* Adds a new goal to this agent to be achieved.
@@ -309,9 +51,7 @@ public class BDIAgent extends Agent {
* @param goal
* the goal to be achieved.
*/
- public final void addGoal(Capability dispatcher, Goal goal) {
- addIntention(dispatcher, goal, null);
- }
+ public void addGoal(Capability dispatcher, Goal goal);
/**
* Adds a new goal to this agent to be achieved and adds a listener to
@@ -324,10 +64,8 @@ public class BDIAgent extends Agent {
* @param goalListener
* the listener to be notified about this goal events.
*/
- public final void addGoal(Capability dispatcher, Goal goal,
- GoalListener goalListener) {
- addIntention(dispatcher, goal, goalListener);
- }
+ public void addGoal(Capability dispatcher, Goal goal,
+ GoalListener goalListener);
/**
* Adds a new goal to this agent to be achieved.
@@ -335,9 +73,7 @@ public class BDIAgent extends Agent {
* @param goal
* the goal to be achieved.
*/
- public final void addGoal(Goal goal) {
- addIntention(null, goal, null);
- }
+ public void addGoal(Goal goal);
/**
* Adds a new goal to this agent to be achieved and adds a listener to
@@ -348,9 +84,7 @@ public class BDIAgent extends Agent {
* @param goalListener
* the listener to be notified.
*/
- public final void addGoal(Goal goal, GoalListener goalListener) {
- addIntention(null, goal, goalListener);
- }
+ public void addGoal(Goal goal, GoalListener goalListener);
/**
* Adds a listener to be notified when about goal events.
@@ -358,48 +92,7 @@ public class BDIAgent extends Agent {
* @param goalListener
* the listener to be notified.
*/
- public final void addGoalListener(GoalListener goalListener) {
- synchronized (goalListeners) {
- goalListeners.add(goalListener);
- }
- }
-
- /**
- * Adds a new goal to this agent to be achieved by creating an intention. It
- * also may add a listener to observe events related to this goal.
- *
- * @param dispatcher
- * the capability that dispatched this goal.
- * @param goal
- * the goal to be achieved.
- * @param goalListener
- * the listener to be notified.
- */
- private final Intention addIntention(Capability dispatcher, Goal goal,
- GoalListener goalListener) {
- Intention intention = null;
- try {
- intention = new Intention(goal, this, dispatcher);
- } catch (IllegalAccessException exc) {
- log.error(exc);
- return null;
- }
-
- synchronized (allIntentions) {
- this.allIntentions.put(goal, intention);
- if (dispatcher == null) {
- agentIntentions.add(intention);
- } else {
- dispatcher.addIntention(intention);
- }
- this.bdiInterpreter.restart();
- if (goalListener != null) {
- intention.addGoalListener(goalListener);
- }
- fireGoalEvent(new GoalEvent(goal));
- return intention;
- }
- }
+ public void addGoalListener(GoalListener goalListener);
/**
* Adds a new softgoal to this agent.
@@ -407,18 +100,16 @@ public class BDIAgent extends Agent {
* @param softgoal
* the softgoal to be pursued.
*/
- public final void addSoftgoal(Softgoal softgoal) {
- synchronized (softgoals) {
- this.softgoals.add(softgoal);
- }
- }
+ public void addSoftgoal(Softgoal softgoal);
- private void computeGoalOwnersMap() {
- this.restrictedAccessOwnersMap = new HashMap<>();
- for (Capability capability : aggregatedCapabilities) {
- ReflectionUtils.addGoalOwner(restrictedAccessOwnersMap, capability);
- }
- }
+ /**
+ * Checks if this agent is able to process the given message.
+ *
+ * @param msg
+ * the message to be checked.
+ * @return true if this agent is able to handle the message.
+ */
+ public boolean canHandle(ACLMessage msg);
/**
* Drops a given goal of this agent, which means setting it as no longer
@@ -428,14 +119,7 @@ public class BDIAgent extends Agent {
* @param goal
* the goal to be dropped.
*/
- public final void dropGoal(Goal goal) {
- synchronized (allIntentions) {
- Intention intention = allIntentions.get(goal);
- if (intention != null) {
- intention.noLongerDesire();
- }
- }
- }
+ public void dropGoal(Goal goal);
/**
* Drops a given softgoal of this agent. If the softgoal is not part of the
@@ -445,104 +129,7 @@ public class BDIAgent extends Agent {
* the softgoal to be dropped.
*/
- public final void dropSoftoal(Softgoal softgoal) {
- synchronized (softgoals) {
- this.softgoals.remove(softgoal);
- }
- }
-
- /**
- * This method is responsible for selecting a set of goals that must be
- * tried to be achieved (intentions) from the set of goals. Its default
- * implementation selects all agent goals (those not dispatched within the
- * scope of a capability) to be achieved, and requests each of its
- * capabilities to filter their goals. Subclasses may override this method
- * to customize this deliberation function.
- *
- * @param agentGoals
- * the set of agent goals, which are goals not dispatched within
- * the scope of a capability.
- * @param capabilityGoals
- * the map from capabilities to their set of goals.
- */
- protected Set<GoalDescription> filter(Set<GoalDescription> agentGoals,
- Map<Capability, Set<GoalDescription>> capabilityGoals) {
- Set<GoalDescription> selectedGoals = new HashSet<>();
- selectedGoals.addAll(agentGoals);
- for (Capability capability : capabilityGoals.keySet()) {
- capability.filter(capabilityGoals.get(capability));
- }
- return selectedGoals;
- }
-
- /**
- * Notifies all listeners, if any, about a goal event.
- *
- * @param goalEvent
- * the event to notify.
- */
- private final void fireGoalEvent(GoalEvent goalEvent) {
- synchronized (goalListeners) {
- for (GoalListener goalListener : goalListeners) {
- goalListener.goalPerformed(goalEvent);
- }
- }
- }
-
- /**
- * Creates a goal event given an intention, and notifies all listeners, if
- * any, about a goal event.
- *
- * @param intention
- * the intention used to create the goal event.
- */
- private final void fireGoalEvent(Intention intention) {
- Goal goal = intention.getGoal();
- GoalStatus status = intention.getStatus();
- log.debug("Goal: " + goal.getClass().getSimpleName() + " (" + status
- + ") - " + goal);
-
- GoalEvent goalEvent = new GoalEvent(goal, status);
- synchronized (goalListeners) {
- for (GoalListener goalListener : goalListeners) {
- goalListener.goalPerformed(goalEvent);
- }
- for (GoalListener goalListener : intention.getGoalListeners()) {
- goalListener.goalPerformed(goalEvent);
- }
- }
- }
-
- /**
- * This method is responsible for generating new goals or dropping existing
- * ones. Its default implementation requests each of its capabilities to
- * generate or drop goals. Subclasses may override this method to customize
- * this options generation function.
- *
- * @param agentGoalUpdateSet
- * the {@link GoalUpdateSet} that contains the set of agent
- * current goals. It has also a set of dropped goals and
- * generated goals, which are used as outputs of this method.
- * @param capabilityGoalUpdateSets
- * the map from capabilities to their goal update set.
- */
- protected void generateGoals(GoalUpdateSet agentGoalUpdateSet,
- Map<Capability, GoalUpdateSet> capabilityGoalUpdateSets) {
- for (Capability capability : capabilityGoalUpdateSets.keySet()) {
- capability.generateGoals(capabilityGoalUpdateSets.get(capability));
- }
- }
-
- /**
- * Returns the root capability of this agent.
- *
- * @return the rootCapability
- */
- public final Set<Capability> getAggregatedCapabilities() {
- synchronized (aggregatedCapabilities) {
- return aggregatedCapabilities;
- }
- }
+ public void dropSoftoal(Softgoal softgoal);
/**
* Returns a collection of all beliefs from all capabilities of this agent.
@@ -550,27 +137,7 @@ public class BDIAgent extends Agent {
*
* @return the collection of all beliefs of this agent.
*/
- public final Collection<Belief<?>> getAllBeliefs() {
- synchronized (aggregatedCapabilities) {
- Collection<Belief<?>> beliefs = new LinkedList<Belief<?>>();
- for (Capability capability : capabilities) {
- beliefs.addAll(capability.getBeliefBase().getBeliefs());
- }
- return beliefs;
- }
- }
-
- /**
- * Returns all capabilities that are part of this agent. This included all
- * capabilities composed or associated with other capabilities.
- *
- * @return the capabilities.
- */
- public final Collection<Capability> getAllCapabilities() {
- synchronized (aggregatedCapabilities) {
- return capabilities;
- }
- }
+ public Collection<Belief<?>> getAllBeliefs();
/**
* Gets all goals of this agent. This goals are the ones in the goal set and
@@ -578,50 +145,21 @@ public class BDIAgent extends Agent {
*
* @return the set of goals.
*/
- public final Set<Goal> getAllGoals() {
- synchronized (allIntentions) {
- return allIntentions.keySet();
- }
- }
+ public Set<Goal> getAllGoals();
/**
* Gets all softgoals of this agent.
*
* @return the set of softgoals.
*/
- public final Set<Softgoal> getAllSoftgoals() {
- synchronized (softgoals) {
- return this.softgoals;
- }
- }
+ public Set<Softgoal> getAllSoftgoals();
/**
* Returns all goal listeners.
*
* @return the goalListeners.
*/
- public final List<GoalListener> getGoalListeners() {
- return goalListeners;
- }
-
- /**
- * Returns the capability instances that owns a dispatched goal, considering
- * the aggregated capabilities of this agent.
- *
- * If this method returns an empty set, it means that this agent cannot add
- * a goal without the scope of a dispatcher that has access to it.
- *
- * @param owner
- * the annotation with the goal owner.
- * @return the capability instances related to this capability that owns the
- * goal, or an empty set if the agent cannot add this goal.
- */
- public Set<Capability> getGoalOwner(GoalOwner owner) {
- Set<Capability> restrictedAccessOwners = restrictedAccessOwnersMap
- .get(owner.capability());
- return restrictedAccessOwners == null ? new HashSet<Capability>()
- : restrictedAccessOwners;
- }
+ public List<GoalListener> getGoalListeners();
/**
* Returns all agent intentions, which are goals that this agent is
@@ -629,44 +167,7 @@ public class BDIAgent extends Agent {
*
* @return the intentions.
*/
- public final Set<Intention> getIntentions() {
- synchronized (allIntentions) {
- Set<Intention> activeIntentions = new HashSet<Intention>();
- for (Intention intention : activeIntentions) {
- if (!GoalStatus.WAITING.equals(intention.getStatus()))
- activeIntentions.add(intention);
- }
- return activeIntentions;
- }
- }
-
- /**
- * This method initializes the BDI agent. It is invoked by the
- * {@link #setup()} method. This is an empty method that should be overriden
- * by subclasses.
- */
- protected void init() {
-
- }
-
- /**
- * Removes a capability from this agent.
- *
- * @param capability
- * capability to be removed.
- *
- * @return true if the capability exists and was removed, false otherwise.
- */
- public final boolean removeCapability(Capability capability) {
- synchronized (aggregatedCapabilities) {
- boolean removed = this.aggregatedCapabilities.remove(capability);
- if (removed) {
- resetAllCapabilities();
- computeGoalOwnersMap();
- }
- return removed;
- }
- }
+ public Set<Intention> getIntentions();
/**
* Removes a goal listener, so it will not be notified about the goal events
@@ -675,118 +176,6 @@ public class BDIAgent extends Agent {
* @param goalListener
* the goal listener to be removed.
*/
- public final void removeGoalListener(GoalListener goalListener) {
- synchronized (goalListeners) {
- goalListeners.remove(goalListener);
- }
- }
-
- final void resetAllCapabilities() {
- synchronized (aggregatedCapabilities) {
- Set<Capability> allCapabilities = new HashSet<>();
- Set<Capability> capabilitiesToBeProcessed = new HashSet<>(
- aggregatedCapabilities);
-
- while (!capabilitiesToBeProcessed.isEmpty()) {
- Capability current = capabilitiesToBeProcessed.iterator()
- .next();
- allCapabilities.add(current);
- for (Capability part : current.getPartCapabilities()) {
- if (!allCapabilities.contains(part))
- capabilitiesToBeProcessed.add(part);
- }
- for (Capability target : current.getAssociatedCapabilities()) {
- if (!allCapabilities.contains(target))
- capabilitiesToBeProcessed.add(target);
- }
- }
-
- Set<Capability> removedCapabilities = new HashSet<>(capabilities);
- removedCapabilities.removeAll(allCapabilities);
- for (Capability capability : removedCapabilities) {
- capability.setMyAgent(null);
- }
-
- Set<Capability> addedCapabilities = new HashSet<>(allCapabilities);
- addedCapabilities.removeAll(capabilities);
- for (Capability capability : addedCapabilities) {
- if (capability.getMyAgent() != null) {
- throw new IllegalArgumentException(
- "Capability already binded to another agent: "
- + capability.getFullId());
- }
- capability.setMyAgent(this);
- }
-
- this.capabilities = allCapabilities;
- log.debug("Capabilities: " + this.capabilities);
- }
- }
-
- /**
- * This method is responsible for reviewing beliefs from this agent. Its
- * default implementation requests each of its capabilities to review their
- * individual set of beliefs. Subclasses may override this method to
- * customize belief revision.
- */
- protected void reviewBeliefs() {
- for (Capability capability : capabilities) {
- capability.reviewBeliefs();
- }
- }
-
- /**
- * This method is responsible for selecting plans to achieve a goals of this
- * agent. Its default implementation requests each of its capabilities to
- * select one of its plans, and this method selects one of them, randomly.
- * Subclasses may override this method to customize plan selection.
- *
- * @param goal
- * the goal to be achieved.
- * @param capabilityPlans
- * the set of candidate plans of each capability, as a map.
- */
- protected Plan selectPlan(Goal goal,
- Map<Capability, Set<Plan>> capabilityPlans) {
- Set<Plan> preselectedPlans = new HashSet<>();
- for (Capability capability : capabilityPlans.keySet()) {
- capability.selectPlan(goal, capabilityPlans.get(capability));
- }
-
- if (preselectedPlans.isEmpty()) {
- return null;
- } else {
- return preselectedPlans.iterator().next();
- }
- }
-
- /**
- * Initializes the BDI agent. It adds the behavior to handle message
- * received and can be processed by capabilities and the
- * {@link BDIInterpreter} behavior as well. It invokes the {@link #init()}
- * method, so that customized initializations can be perfomed by subclasses.
- *
- * @see jade.core.Agent#setup()
- */
- @Override
- protected final void setup() {
- this.addBehaviour(new BDIAgentMsgReceiver(this));
- this.addBehaviour(bdiInterpreter);
- init();
- }
-
- /**
- * Removes all capabilities of this agent, before it stops its execution.
- *
- * @see jade.core.Agent#takeDown()
- */
- @Override
- protected void takeDown() {
- synchronized (aggregatedCapabilities) {
- Iterator<Capability> iterator = aggregatedCapabilities.iterator();
- while (iterator.hasNext())
- removeCapability(iterator.next());
- }
- }
+ public void removeGoalListener(GoalListener goalListener);
}
diff --git a/bdi-jade/src/bdi4jade/core/Capability.java b/bdi-jade/src/bdi4jade/core/Capability.java
index 395a0e2..2ee9629 100644
--- a/bdi-jade/src/bdi4jade/core/Capability.java
+++ b/bdi-jade/src/bdi4jade/core/Capability.java
@@ -74,7 +74,7 @@ public class Capability implements Serializable {
protected final String id;
private final Collection<Intention> intentions;
protected final Log log;
- private BDIAgent myAgent;
+ private AbstractBDIAgent myAgent;
private OptionGenerationFunction optionGenerationFunction;
private final List<Class<? extends Capability>> parentCapabilities;
private final Set<Capability> partCapabilities;
@@ -328,7 +328,7 @@ public class Capability implements Serializable {
*
* @see DeliberationFunction
*/
- public final Set<GoalDescription> filter(Set<GoalDescription> goals) {
+ public final Set<Goal> filter(Set<GoalDescription> goals) {
return this.deliberationFunction.filter(goals);
}
@@ -654,7 +654,7 @@ public class Capability implements Serializable {
* @param myAgent
* the myAgent to set
*/
- final void setMyAgent(BDIAgent myAgent) {
+ final void setMyAgent(AbstractBDIAgent myAgent) {
synchronized (this) {
if (this.myAgent != null && myAgent == null) {
takeDown();
diff --git a/bdi-jade/src/bdi4jade/core/Intention.java b/bdi-jade/src/bdi4jade/core/Intention.java
index c4da57d..06d5274 100644
--- a/bdi-jade/src/bdi4jade/core/Intention.java
+++ b/bdi-jade/src/bdi4jade/core/Intention.java
@@ -62,7 +62,7 @@ public class Intention {
private final Goal goal;
private final List<GoalListener> goalListeners;
private final Log log;
- private final BDIAgent myAgent;
+ private final AbstractBDIAgent myAgent;
private boolean noLongerDesired;
private final Set<Capability> owners;
private boolean unachievable;
@@ -77,7 +77,7 @@ public class Intention {
* @param bdiAgent
* the bdiAgent associated with this intention.
*/
- public Intention(Goal goal, BDIAgent bdiAgent)
+ public Intention(Goal goal, AbstractBDIAgent bdiAgent)
throws IllegalAccessException {
this(goal, bdiAgent, null);
}
@@ -94,7 +94,7 @@ public class Intention {
* @param dispatcher
* the Capability that dispatched the goal.
*/
- public Intention(Goal goal, BDIAgent bdiAgent, Capability dispatcher)
+ public Intention(Goal goal, AbstractBDIAgent bdiAgent, Capability dispatcher)
throws IllegalAccessException {
this.log = LogFactory.getLog(this.getClass());
this.goal = goal;
@@ -243,7 +243,7 @@ public class Intention {
*
* @return the myAgent.
*/
- public BDIAgent getMyAgent() {
+ public AbstractBDIAgent getMyAgent() {
return myAgent;
}
diff --git a/bdi-jade/src/bdi4jade/core/MultipleCapabilityAgent.java b/bdi-jade/src/bdi4jade/core/MultipleCapabilityAgent.java
new file mode 100644
index 0000000..11928da
--- /dev/null
+++ b/bdi-jade/src/bdi4jade/core/MultipleCapabilityAgent.java
@@ -0,0 +1,113 @@
+//----------------------------------------------------------------------------
+// Copyright (C) 2011 Ingrid Nunes
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// To contact the authors:
+// http://inf.ufrgs.br/~ingridnunes/bdi4jade/
+//
+//----------------------------------------------------------------------------
+
+package bdi4jade.core;
+
+import java.util.Collection;
+import java.util.Set;
+
+/**
+ * This class is a BDIAgent that has multiple aggregated capabilities.
+ *
+ * @author Ingrid Nunes
+ */
+public class MultipleCapabilityAgent extends AbstractBDIAgent {
+
+ private static final long serialVersionUID = 6369037881807947402L;
+
+ /**
+ * Default constructor.
+ */
+ public MultipleCapabilityAgent() {
+
+ }
+
+ /**
+ * Creates a new BDIAgent with a single capability.
+ *
+ * @param capability
+ * the capability to be added to the agent.
+ */
+ public MultipleCapabilityAgent(Capability capability) {
+ super();
+ this.addCapability(capability);
+ }
+
+ /**
+ * Creates a new BDIAgent with a set of capabilities.
+ *
+ * @param capabilities
+ * the capabilities to be added to the agent.
+ */
+ public MultipleCapabilityAgent(Capability[] capabilities) {
+ super();
+ for (Capability capability : capabilities) {
+ this.addCapability(capability);
+ }
+ }
+
+ /**
+ * Creates a new BDIAgent with a set of capabilities.
+ *
+ * @param capabilities
+ * the capabilities to be added to the agent.
+ */
+ public MultipleCapabilityAgent(Collection<Capability> capabilities) {
+ super();
+ for (Capability capability : capabilities) {
+ this.addCapability(capability);
+ }
+ }
+
+ /**
+ * @see bdi4jade.core.AbstractBDIAgent#addCapability(bdi4jade.core.Capability)
+ */
+ @Override
+ public final void addCapability(Capability capability) {
+ super.addCapability(capability);
+ }
+
+ /**
+ * @see bdi4jade.core.AbstractBDIAgent#getAggregatedCapabilities()
+ */
+ @Override
+ public final Set<Capability> getAggregatedCapabilities() {
+ return super.getAggregatedCapabilities();
+ }
+
+ /**
+ * @see bdi4jade.core.AbstractBDIAgent#getAllCapabilities()
+ */
+ @Override
+ public final Collection<Capability> getAllCapabilities() {
+ return super.getAllCapabilities();
+ }
+
+ /**
+ * @see bdi4jade.core.AbstractBDIAgent#removeCapability(bdi4jade.core.Capability)
+ */
+ @Override
+ public final boolean removeCapability(Capability capability) {
+ return super.removeCapability(capability);
+ }
+
+}
diff --git a/bdi-jade/src/bdi4jade/core/SingleCapabilityAgent.java b/bdi-jade/src/bdi4jade/core/SingleCapabilityAgent.java
new file mode 100644
index 0000000..fefe2c8
--- /dev/null
+++ b/bdi-jade/src/bdi4jade/core/SingleCapabilityAgent.java
@@ -0,0 +1,77 @@
+//----------------------------------------------------------------------------
+// Copyright (C) 2011 Ingrid Nunes
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// To contact the authors:
+// http://inf.ufrgs.br/~ingridnunes/bdi4jade/
+//
+//----------------------------------------------------------------------------
+
+package bdi4jade.core;
+
+/**
+ * This class is a BDIAgent that has a single capability.
+ *
+ * @author Ingrid Nunes
+ */
+public class SingleCapabilityAgent extends AbstractBDIAgent {
+
+ private static final long serialVersionUID = 6369037881807947402L;
+
+ private Capability capability;
+
+ /**
+ * Default constructor. Creates a new BDIAgent with a single capability.
+ */
+ public SingleCapabilityAgent() {
+ this(new Capability());
+ }
+
+ /**
+ * Creates a new BDIAgent with the given capability.
+ *
+ * @param capability
+ * the capability to be added to the agent.
+ */
+ public SingleCapabilityAgent(Capability capability) {
+ super();
+ setCapability(capability);
+ }
+
+ /**
+ * Returns the capability of this agent.
+ *
+ * @return the capability.
+ */
+ public synchronized Capability getCapability() {
+ return capability;
+ }
+
+ /**
+ * Sets the capability of this agent.
+ *
+ * @param capability
+ * the capability to set.
+ */
+ public synchronized void setCapability(Capability capability) {
+ if (this.capability != null) {
+ this.removeCapability(this.capability);
+ }
+ this.addCapability(capability);
+ this.capability = capability;
+ }
+
+}
diff --git a/bdi-jade/src/bdi4jade/message/BDIAgentMsgReceiver.java b/bdi-jade/src/bdi4jade/message/BDIAgentMsgReceiver.java
index 4e414d9..ebbc865 100644
--- a/bdi-jade/src/bdi4jade/message/BDIAgentMsgReceiver.java
+++ b/bdi-jade/src/bdi4jade/message/BDIAgentMsgReceiver.java
@@ -28,16 +28,10 @@ import jade.lang.acl.MessageTemplate;
import jade.lang.acl.MessageTemplate.MatchExpression;
import jade.proto.states.MsgReceiver;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Map;
-import java.util.Set;
-
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
-import bdi4jade.core.BDIAgent;
-import bdi4jade.core.Capability;
+import bdi4jade.core.AbstractBDIAgent;
/**
* This class extends the {@link MsgReceiver} behavior from the JADE platform
@@ -63,29 +57,16 @@ public class BDIAgentMsgReceiver extends MsgReceiver {
private static final long serialVersionUID = -1076583615928481034L;
- private Set<Capability> getCanProcessCapabilities(final ACLMessage msg) {
- Set<Capability> capabilities = new HashSet<Capability>();
- for (Capability capability : getMyAgent()
- .getAggregatedCapabilities()) {
- if (capability.canHandle(msg)) {
- capabilities.add(capability);
- }
- }
- return capabilities;
- }
-
/**
* @see jade.lang.acl.MessageTemplate.MatchExpression#match(jade.lang.acl.ACLMessage)
*/
@Override
public boolean match(ACLMessage msg) {
- Set<Capability> capabilities = getCanProcessCapabilities(msg);
- if (!capabilities.isEmpty()) {
- synchronized (msgs) {
- msgs.put(msg, capabilities);
- }
+ log.debug("Message received.");
+ if (getMyAgent().canHandle(msg)) {
return true;
} else {
+ log.debug("Message cannot be handled:" + msg);
return false;
}
}
@@ -96,7 +77,6 @@ public class BDIAgentMsgReceiver extends MsgReceiver {
private static final long serialVersionUID = -4435254708782532901L;
private final Log log;
- private final Map<ACLMessage, Set<Capability>> msgs;
/**
* Initializes this message receiver, which is associated with a BDI agent.
@@ -104,11 +84,10 @@ public class BDIAgentMsgReceiver extends MsgReceiver {
* @param agent
* the BDI agent that this behavior is associated with.
*/
- public BDIAgentMsgReceiver(BDIAgent agent) {
+ public BDIAgentMsgReceiver(AbstractBDIAgent agent) {
super(agent, MessageTemplate.MatchAll(), INFINITE, new DataStore(),
MSG_KEY);
this.template = new MessageTemplate(new BDIAgentMatchExpression());
- this.msgs = new HashMap<ACLMessage, Set<Capability>>();
this.log = LogFactory.getLog(this.getClass());
}
@@ -123,8 +102,8 @@ public class BDIAgentMsgReceiver extends MsgReceiver {
return false;
}
- private BDIAgent getMyAgent() {
- return (BDIAgent) this.myAgent;
+ private AbstractBDIAgent getMyAgent() {
+ return (AbstractBDIAgent) this.myAgent;
}
/**
@@ -136,18 +115,9 @@ public class BDIAgentMsgReceiver extends MsgReceiver {
@Override
protected void handleMessage(ACLMessage msg) {
log.debug("Message received.");
- synchronized (msgs) {
- Set<Capability> capabilities = msgs.get(msg);
- if (capabilities != null) {
- MessageGoal goal = new MessageGoal(msg);
- log.debug("This capabilities can process the message:");
- for (Capability capability : capabilities) {
- log.debug("* " + capability);
- }
- getMyAgent().addGoal(goal);
- msgs.remove(msg);
- }
- }
+ MessageGoal goal = new MessageGoal(msg);
+ getMyAgent().addGoal(goal);
+ log.debug("Message goal added for message: " + msg);
}
}
diff --git a/bdi-jade/src/bdi4jade/reasoning/DefaultDeliberationFunction.java b/bdi-jade/src/bdi4jade/reasoning/DefaultDeliberationFunction.java
index c2227db..0ad8af7 100644
--- a/bdi-jade/src/bdi4jade/reasoning/DefaultDeliberationFunction.java
+++ b/bdi-jade/src/bdi4jade/reasoning/DefaultDeliberationFunction.java
@@ -26,6 +26,7 @@ import java.util.HashSet;
import java.util.Set;
import bdi4jade.core.GoalUpdateSet.GoalDescription;
+import bdi4jade.goal.Goal;
/**
* This class is the default implementation of the strategy
@@ -43,8 +44,12 @@ public class DefaultDeliberationFunction extends AbstractReasoningStrategy
* @see DeliberationFunction#filter(Set)
*/
@Override
- public Set<GoalDescription> filter(Set<GoalDescription> goals) {
- return new HashSet<>(goals);
+ public Set<Goal> filter(Set<GoalDescription> goals) {
+ Set<Goal> selectedGoals = new HashSet<>();
+ for (GoalDescription goalDescription : goals) {
+ selectedGoals.add(goalDescription.getGoal());
+ }
+ return selectedGoals;
}
}
diff --git a/bdi-jade/src/bdi4jade/reasoning/DeliberationFunction.java b/bdi-jade/src/bdi4jade/reasoning/DeliberationFunction.java
index 991c0d6..1eb0f02 100644
--- a/bdi-jade/src/bdi4jade/reasoning/DeliberationFunction.java
+++ b/bdi-jade/src/bdi4jade/reasoning/DeliberationFunction.java
@@ -25,6 +25,7 @@ package bdi4jade.reasoning;
import java.util.Set;
import bdi4jade.core.GoalUpdateSet.GoalDescription;
+import bdi4jade.goal.Goal;
/**
* This interface defines the deliberation function to be used within the scope
@@ -43,9 +44,8 @@ public interface DeliberationFunction extends ReasoningStrategy {
* the list of current goals dispatched by the capability
* associated with this strategy.
*
- * @return the list of selected goals (which are in the for of
- * {@link GoalDescription}), which will become intentions.
+ * @return the list of selected goals, which will become intentions.
*/
- public Set<GoalDescription> filter(Set<GoalDescription> goals);
+ public Set<Goal> filter(Set<GoalDescription> goals);
}
diff --git a/bdi-jade-test/src/bdi4jade/examples/BDI4JADEExamplesAction.java b/bdi-jade-test/src/bdi4jade/examples/BDI4JADEExamplesAction.java
new file mode 100644
index 0000000..4816acb
--- /dev/null
+++ b/bdi-jade-test/src/bdi4jade/examples/BDI4JADEExamplesAction.java
@@ -0,0 +1,54 @@
+package bdi4jade.examples;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Set;
+
+import javax.swing.AbstractAction;
+import javax.swing.Action;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import bdi4jade.core.AbstractBDIAgent;
+
+/**
+ * This class is an abstract action used as a base for actions to test BDI4JADE
+ * agents. Each action has an agent and a name, and subclasses should implement
+ * the {@link #actionPerformed(java.awt.event.ActionEvent)} method to add goals
+ * to agents, for example.
+ *
+ * @author Ingrid Nunes
+ */
+public abstract class BDI4JADEExamplesAction extends AbstractAction {
+
+ private static final long serialVersionUID = 6251170147656457707L;
+
+ protected final Log log;
+
+ protected BDI4JADEExamplesAction() {
+ super();
+ this.log = LogFactory.getLog(this.getClass());
+
+ super.putValue(Action.ACCELERATOR_KEY, null);
+ super.putValue(Action.ACTION_COMMAND_KEY, this.getClass()
+ .getSimpleName());
+ super.putValue(Action.LONG_DESCRIPTION, null);
+ super.putValue(Action.MNEMONIC_KEY, null);
+ super.putValue(Action.NAME, null);
+ super.putValue(Action.SHORT_DESCRIPTION, null);
+ super.putValue(Action.SMALL_ICON, null);
+ super.setEnabled(true);
+ }
+
+ public Map<String, AbstractBDIAgent> getAgentMap() {
+ Map<String, AbstractBDIAgent> agentMap = new HashMap<>();
+ for (AbstractBDIAgent agent : getAgents()) {
+ agentMap.put(agent.getClass().getSimpleName(), agent);
+ }
+ return agentMap;
+ }
+
+ public abstract Set<AbstractBDIAgent> getAgents();
+
+}
diff --git a/bdi-jade-test/src/bdi4jade/examples/BDI4JADEExamplesPanel.java b/bdi-jade-test/src/bdi4jade/examples/BDI4JADEExamplesPanel.java
new file mode 100644
index 0000000..784adbd
--- /dev/null
+++ b/bdi-jade-test/src/bdi4jade/examples/BDI4JADEExamplesPanel.java
@@ -0,0 +1,79 @@
+package bdi4jade.examples;
+
+import java.awt.GridLayout;
+import java.awt.event.ActionEvent;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+import javax.swing.Action;
+import javax.swing.JButton;
+import javax.swing.JPanel;
+
+import bdi4jade.core.AbstractBDIAgent;
+import bdi4jade.examples.helloworld.HelloWorldAgent;
+import bdi4jade.examples.helloworld.HelloWorldAgent.HelloWorldGoal;
+
+/**
+ * This class is a panel that is used as content pane of the application with
+ * examples of BDI4JADE. It has a set of {@link BDI4JADEExamplesAction}, and
+ * creates a button to perform each of them.
+ *
+ * @author Ingrid Nunes
+ */
+public class BDI4JADEExamplesPanel extends JPanel {
+
+ private class HelloWorldAction extends BDI4JADEExamplesAction {
+
+ private static final long serialVersionUID = 2100583035268414082L;
+
+ private final HelloWorldAgent helloWorldAgent;
+
+ public HelloWorldAction() {
+ super.putValue(Action.NAME, "Hello World Agent");
+ this.helloWorldAgent = new HelloWorldAgent();
+ }
+
+ @Override
+ public void actionPerformed(ActionEvent e) {
+ helloWorldAgent.addGoal(new HelloWorldGoal("reader"));
+ }
+
+ @Override
+ public Set<AbstractBDIAgent> getAgents() {
+ Set<AbstractBDIAgent> agents = new HashSet<>();
+ agents.add(helloWorldAgent);
+ return agents;
+ }
+ }
+
+ private static final long serialVersionUID = -1080267169700651610L;
+
+ private final BDI4JADEExamplesAction[] actions;
+
+ // agents.put(HelloWorldParamAgent.class.getSimpleName(),
+ // new HelloWorldParamAgent());
+ // agents.put(BDIAgent1.MY_NAME, new BDIAgent1());
+ // agents.put(BDIAgent2.MY_NAME, new BDIAgent2());
+ // agents.put(MyAgent.class.getSimpleName(), new MyAgent());
+ // agents.put(NestedCapabilitiesAgent.class.getSimpleName(),
+ // new NestedCapabilitiesAgent());
+
+ public BDI4JADEExamplesPanel() {
+ this.actions = new BDI4JADEExamplesAction[] { new HelloWorldAction() };
+ this.setLayout(new GridLayout(actions.length, 1));
+ for (BDI4JADEExamplesAction action : actions) {
+ this.add(new JButton(action));
+ }
+ }
+
+ public Map<String, AbstractBDIAgent> getAgents() {
+ Map<String, AbstractBDIAgent> agents = new HashMap<>();
+ for (BDI4JADEExamplesAction action : actions) {
+ agents.putAll(action.getAgentMap());
+ }
+ return agents;
+ }
+
+}
diff --git a/bdi-jade-test/src/bdi4jade/examples/BDIAgent1.java b/bdi-jade-test/src/bdi4jade/examples/BDIAgent1.java
index 27ebc0e..d6aba50 100644
--- a/bdi-jade-test/src/bdi4jade/examples/BDIAgent1.java
+++ b/bdi-jade-test/src/bdi4jade/examples/BDIAgent1.java
@@ -22,14 +22,14 @@
package bdi4jade.examples;
-import bdi4jade.core.BDIAgent;
+import bdi4jade.core.MultipleCapabilityAgent;
import bdi4jade.examples.ping.PingPongCapability;
/**
* @author ingrid
*
*/
-public class BDIAgent1 extends BDIAgent {
+public class BDIAgent1 extends MultipleCapabilityAgent {
public static final String MY_NAME = "AGENT_1";
private static final long serialVersionUID = -8505187840524213951L;
diff --git a/bdi-jade-test/src/bdi4jade/examples/BDIAgent2.java b/bdi-jade-test/src/bdi4jade/examples/BDIAgent2.java
index a8e53e1..6d247e8 100644
--- a/bdi-jade-test/src/bdi4jade/examples/BDIAgent2.java
+++ b/bdi-jade-test/src/bdi4jade/examples/BDIAgent2.java
@@ -22,14 +22,14 @@
package bdi4jade.examples;
-import bdi4jade.core.BDIAgent;
+import bdi4jade.core.MultipleCapabilityAgent;
import bdi4jade.examples.ping.PingPongCapability;
/**
* @author ingrid
*
*/
-public class BDIAgent2 extends BDIAgent {
+public class BDIAgent2 extends MultipleCapabilityAgent {
private static final long serialVersionUID = -8505187840524213951L;
public static final String MY_NAME = "AGENT_2";
diff --git a/bdi-jade-test/src/bdi4jade/examples/blocksworld/BlocksWorldAgent.java b/bdi-jade-test/src/bdi4jade/examples/blocksworld/BlocksWorldAgent.java
index 9038045..d1b0b81 100644
--- a/bdi-jade-test/src/bdi4jade/examples/blocksworld/BlocksWorldAgent.java
+++ b/bdi-jade-test/src/bdi4jade/examples/blocksworld/BlocksWorldAgent.java
@@ -24,8 +24,8 @@ package bdi4jade.examples.blocksworld;
import bdi4jade.belief.BeliefSet;
import bdi4jade.belief.TransientBeliefSet;
-import bdi4jade.core.BDIAgent;
import bdi4jade.core.Capability;
+import bdi4jade.core.MultipleCapabilityAgent;
import bdi4jade.examples.blocksworld.domain.Clear;
import bdi4jade.examples.blocksworld.domain.On;
import bdi4jade.examples.blocksworld.domain.Thing;
@@ -42,7 +42,7 @@ import bdi4jade.plan.DefaultPlan;
* @author ingrid
*
*/
-public class BlocksWorldAgent extends BDIAgent {
+public class BlocksWorldAgent extends MultipleCapabilityAgent {
public static final String BELIEF_CLEAR = "clear";
public static final String BELIEF_ON = "on";
diff --git a/bdi-jade-test/src/bdi4jade/examples/blocksworld/BlocksWorldApp.java b/bdi-jade-test/src/bdi4jade/examples/blocksworld/BlocksWorldApp.java
index edf3837..2580b41 100644
--- a/bdi-jade-test/src/bdi4jade/examples/blocksworld/BlocksWorldApp.java
+++ b/bdi-jade-test/src/bdi4jade/examples/blocksworld/BlocksWorldApp.java
@@ -21,7 +21,7 @@ import org.apache.log4j.PropertyConfigurator;
import bdi4jade.event.GoalEvent;
import bdi4jade.event.GoalListener;
-import bdi4jade.examples.AgentStarter;
+import bdi4jade.examples.BDI4JADEExamplesApp;
import bdi4jade.examples.blocksworld.domain.On;
import bdi4jade.examples.blocksworld.domain.Thing;
import bdi4jade.examples.blocksworld.goal.AchieveBlocksStacked;
@@ -39,7 +39,7 @@ public class BlocksWorldApp implements GoalListener {
new On(Thing.BLOCK_1, Thing.BLOCK_2) };
public static void main(String[] args) {
- PropertyConfigurator.configure(AgentStarter.class
+ PropertyConfigurator.configure(BDI4JADEExamplesApp.class
.getResource("log4j.properties"));
new BlocksWorldApp();
}
diff --git a/bdi-jade-test/src/bdi4jade/examples/compositegoal/CompositeGoalCapability.java b/bdi-jade-test/src/bdi4jade/examples/compositegoal/CompositeGoalCapability.java
index 0cf8ddd..49b55f4 100644
--- a/bdi-jade-test/src/bdi4jade/examples/compositegoal/CompositeGoalCapability.java
+++ b/bdi-jade-test/src/bdi4jade/examples/compositegoal/CompositeGoalCapability.java
@@ -137,7 +137,7 @@ public class CompositeGoalCapability extends Capability implements GoalListener
&& event.getGoal() instanceof CompositeGoal) {
log.info(event.getGoal() + " Status: " + event.getStatus());
log.info("Goal finished!! Removing capability of this agent...");
- getMyAgent().removeCapability(this);
+ //getMyAgent().removeCapability(this);
}
}
diff --git a/bdi-jade-test/src/bdi4jade/examples/helloworld/HelloWorldAgent.java b/bdi-jade-test/src/bdi4jade/examples/helloworld/HelloWorldAgent.java
index 9a405ad..60f95f7 100644
--- a/bdi-jade-test/src/bdi4jade/examples/helloworld/HelloWorldAgent.java
+++ b/bdi-jade-test/src/bdi4jade/examples/helloworld/HelloWorldAgent.java
@@ -22,41 +22,48 @@
package bdi4jade.examples.helloworld;
-import bdi4jade.core.BDIAgent;
-import bdi4jade.core.Capability;
+import bdi4jade.core.SingleCapabilityAgent;
import bdi4jade.goal.Goal;
import bdi4jade.plan.DefaultPlan;
+import bdi4jade.plan.Plan.EndState;
+import bdi4jade.plan.planbody.AbstractPlanBody;
-public class HelloWorldAgent extends BDIAgent {
+public class HelloWorldAgent extends SingleCapabilityAgent {
- private static final long serialVersionUID = 2712019445290687786L;
+ public static class HelloWorldGoal implements Goal {
- protected void init() {
- Capability capability = new Capability();
- capability.getPlanLibrary().addPlan(
- new DefaultPlan(HelloWorldGoal.class, HelloWorldPlan.class));
- this.addCapability(capability);
+ private static final long serialVersionUID = -9039447524062487795L;
- addGoal(new HelloWorldGoal("reader"));
- }
+ private String name;
-}
+ public HelloWorldGoal(String name) {
+ this.name = name;
+ }
+
+ public String getName() {
+ return name;
+ }
+ }
-/**
- * @author ingridn
- *
- */
-class HelloWorldGoal implements Goal {
+ public static class HelloWorldPlanBody extends AbstractPlanBody {
- private static final long serialVersionUID = -9039447524062487795L;
+ private static final long serialVersionUID = -9039447524062487795L;
- private String name;
+ public void action() {
+ System.out.println("Hello, "
+ + ((HelloWorldGoal) getGoal()).getName() + "!");
+ setEndState(EndState.SUCCESSFULL);
+ }
- public HelloWorldGoal(String name) {
- this.name = name;
}
- public String getName() {
- return name;
+ private static final long serialVersionUID = 2712019445290687786L;
+
+ public HelloWorldAgent() {
+ getCapability().getPlanLibrary()
+ .addPlan(
+ new DefaultPlan(HelloWorldGoal.class,
+ HelloWorldPlanBody.class));
}
+
}
diff --git a/bdi-jade-test/src/bdi4jade/examples/nestedcapabilities/NestedCapabilitiesAgent.java b/bdi-jade-test/src/bdi4jade/examples/nestedcapabilities/NestedCapabilitiesAgent.java
index 4ae3b8f..7ac6c85 100644
--- a/bdi-jade-test/src/bdi4jade/examples/nestedcapabilities/NestedCapabilitiesAgent.java
+++ b/bdi-jade-test/src/bdi4jade/examples/nestedcapabilities/NestedCapabilitiesAgent.java
@@ -23,8 +23,8 @@
package bdi4jade.examples.nestedcapabilities;
import bdi4jade.belief.TransientBelief;
-import bdi4jade.core.BDIAgent;
import bdi4jade.core.Capability;
+import bdi4jade.core.MultipleCapabilityAgent;
import bdi4jade.goal.Goal;
import bdi4jade.plan.DefaultPlan;
import bdi4jade.plan.planbody.PlanBody;
@@ -37,7 +37,7 @@ class MyGoal implements Goal {
private static final long serialVersionUID = -5054184951317760743L;
}
-public class NestedCapabilitiesAgent extends BDIAgent {
+public class NestedCapabilitiesAgent extends MultipleCapabilityAgent {
public enum Belief {
diff --git a/bdi-jade-test/src/bdi4jade/examples/planfailed/PlanFailedCapability.java b/bdi-jade-test/src/bdi4jade/examples/planfailed/PlanFailedCapability.java
index 58fbb94..49c8b16 100644
--- a/bdi-jade-test/src/bdi4jade/examples/planfailed/PlanFailedCapability.java
+++ b/bdi-jade-test/src/bdi4jade/examples/planfailed/PlanFailedCapability.java
@@ -85,7 +85,7 @@ public class PlanFailedCapability extends Capability implements GoalListener {
counter++;
if (counter >= GOALS) {
log.info("Goal finished!! Removing capability of this agent...");
- getMyAgent().removeCapability(this);
+ // TODO getMyAgent().removeCapability(this);
}
}
}
diff --git a/bdi-jade-test/src/bdi4jade/examples/planparameter/HelloWorldParamAgent.java b/bdi-jade-test/src/bdi4jade/examples/planparameter/HelloWorldParamAgent.java
index 62227ed..48cd0d4 100644
--- a/bdi-jade-test/src/bdi4jade/examples/planparameter/HelloWorldParamAgent.java
+++ b/bdi-jade-test/src/bdi4jade/examples/planparameter/HelloWorldParamAgent.java
@@ -24,14 +24,15 @@ package bdi4jade.examples.planparameter;
import bdi4jade.annotation.Parameter;
import bdi4jade.annotation.Parameter.Direction;
-import bdi4jade.core.BDIAgent;
import bdi4jade.core.Capability;
+import bdi4jade.core.SingleCapabilityAgent;
import bdi4jade.event.GoalEvent;
import bdi4jade.event.GoalListener;
import bdi4jade.goal.Goal;
import bdi4jade.plan.DefaultPlan;
-public class HelloWorldParamAgent extends BDIAgent implements GoalListener {
+public class HelloWorldParamAgent extends SingleCapabilityAgent implements
+ GoalListener {
public class HelloWorldParamGoal implements Goal {
@@ -73,7 +74,7 @@ public class HelloWorldParamAgent extends BDIAgent implements GoalListener {
capability.getPlanLibrary().addPlan(
new DefaultPlan(HelloWorldParamGoal.class,
HelloWorldParamPlan.class));
- addCapability(capability);
+ setCapability(capability);
addGoal(new HelloWorldParamGoal("reader"), this);
}
diff --git a/bdi-jade-test/src/bdi4jade/examples/planselection/ExperimentRunner.java b/bdi-jade-test/src/bdi4jade/examples/planselection/ExperimentRunner.java
index f26d649..b5140d7 100644
--- a/bdi-jade-test/src/bdi4jade/examples/planselection/ExperimentRunner.java
+++ b/bdi-jade-test/src/bdi4jade/examples/planselection/ExperimentRunner.java
@@ -37,7 +37,7 @@ import org.apache.log4j.PropertyConfigurator;
import bdi4jade.event.GoalEvent;
import bdi4jade.event.GoalListener;
-import bdi4jade.examples.AgentStarter;
+import bdi4jade.examples.BDI4JADEExamplesApp;
/**
* @author ingrid
@@ -48,7 +48,7 @@ public class ExperimentRunner implements GoalListener {
public static final int ITERATIONS = 5000;
public static void main(String[] args) {
- PropertyConfigurator.configure(AgentStarter.class
+ PropertyConfigurator.configure(BDI4JADEExamplesApp.class
.getResource("log4j.properties"));
ExperimentRunner runner = new ExperimentRunner();
runner.run();
@@ -98,7 +98,7 @@ public class ExperimentRunner implements GoalListener {
} else {
log.info("Iterations finished!!");
log.info(((GenericValueFunction<?>) transportationAgent
- .getRootCapability().getBeliefBase()
+ .getCapability().getBeliefBase()
.getBelief(TransportationAgent.SATISFACTION).getValue())
.stats());
}
diff --git a/bdi-jade-test/src/bdi4jade/examples/planselection/TransportationAgent.java b/bdi-jade-test/src/bdi4jade/examples/planselection/TransportationAgent.java
index e58f77a..51de8ee 100644
--- a/bdi-jade-test/src/bdi4jade/examples/planselection/TransportationAgent.java
+++ b/bdi-jade-test/src/bdi4jade/examples/planselection/TransportationAgent.java
@@ -28,8 +28,7 @@ import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import bdi4jade.belief.TransientBelief;
-import bdi4jade.core.BDIAgent;
-import bdi4jade.core.Capability;
+import bdi4jade.core.SingleCapabilityAgent;
import bdi4jade.extension.planselection.utilitybased.SoftgoalPreferences;
import bdi4jade.extension.planselection.utilitybased.UtilityBasedBDIAgent;
import bdi4jade.goal.Softgoal;
@@ -39,7 +38,7 @@ import bdi4jade.plan.Plan;
* @author ingrid
*
*/
-public class TransportationAgent extends BDIAgent {
+public class TransportationAgent extends SingleCapabilityAgent {
public static final String SATISFACTION = "Satisfaction";
@@ -47,17 +46,11 @@ public class TransportationAgent extends BDIAgent {
private final Log log;
private final Random rand;
- private final Capability rootCapability;
public TransportationAgent() {
+ super(new UtilityBasedBDIAgent());
this.log = LogFactory.getLog(this.getClass());
this.rand = new Random(System.currentTimeMillis());
- this.rootCapability = new UtilityBasedBDIAgent();
- this.addCapability(rootCapability);
- }
-
- public Capability getRootCapability() {
- return rootCapability;
}
protected void init() {
@@ -65,19 +58,16 @@ public class TransportationAgent extends BDIAgent {
this.addSoftgoal(softgoal);
}
for (Plan plan : Plans.PLANS) {
- this.getRootCapability().getPlanLibrary().addPlan(plan);
+ getCapability().getPlanLibrary().addPlan(plan);
}
- this.getRootCapability()
- .getBeliefBase()
- .addBelief(
- new TransientBelief<GenericValueFunction<Integer>>(
- SATISFACTION,
- new GenericValueFunction<Integer>()));
+ getCapability().getBeliefBase().addBelief(
+ new TransientBelief<GenericValueFunction<Integer>>(
+ SATISFACTION, new GenericValueFunction<Integer>()));
}
public void updatePreferences() {
SoftgoalPreferences preferences = (SoftgoalPreferences) this
- .getRootCapability().getBeliefBase()
+ .getCapability().getBeliefBase()
.getBelief(SoftgoalPreferences.NAME);
double total = 0;
diff --git a/bdi-jade-test/src/bdi4jade/examples/template/MyAgent.java b/bdi-jade-test/src/bdi4jade/examples/template/MyAgent.java
index 2abcf7b..74736d3 100644
--- a/bdi-jade-test/src/bdi4jade/examples/template/MyAgent.java
+++ b/bdi-jade-test/src/bdi4jade/examples/template/MyAgent.java
@@ -22,8 +22,8 @@
package bdi4jade.examples.template;
-import bdi4jade.core.BDIAgent;
import bdi4jade.core.Capability;
+import bdi4jade.core.MultipleCapabilityAgent;
import bdi4jade.examples.template.goal.MyGoal;
import bdi4jade.examples.template.plan.MyPlan1;
import bdi4jade.examples.template.plan.MyPlan2;
@@ -35,7 +35,7 @@ import bdi4jade.goal.Softgoal;
* @author ingrid
*
*/
-public class MyAgent extends BDIAgent {
+public class MyAgent extends MultipleCapabilityAgent {
static final long serialVersionUID = 2712019445290687786L;