bdi4jade

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 7f96efd..fe58077 100644
--- a/bdi-jade/src/br/ufrgs/inf/bdi4jade/core/BDIAgent.java
+++ b/bdi-jade/src/br/ufrgs/inf/bdi4jade/core/BDIAgent.java
@@ -49,6 +49,7 @@ import br.ufrgs.inf.bdi4jade.reasoning.BeliefRevisionStrategy;
 import br.ufrgs.inf.bdi4jade.reasoning.DeliberationFunction;
 import br.ufrgs.inf.bdi4jade.reasoning.OptionGenerationFunction;
 import br.ufrgs.inf.bdi4jade.reasoning.PlanSelectionStrategy;
+import br.ufrgs.inf.bdi4jade.softgoal.Softgoal;
 import br.ufrgs.inf.bdi4jade.util.DefaultCapability;
 import br.ufrgs.inf.bdi4jade.util.reasoning.DefaultBeliefRevisionStrategy;
 import br.ufrgs.inf.bdi4jade.util.reasoning.DefaultDeliberationFunction;
@@ -185,18 +186,20 @@ public class BDIAgent extends Agent {
 	private static final long serialVersionUID = -841774495336214256L;
 	private final BDIInterpreter bdiInterpreter;
 	private BeliefRevisionStrategy beliefRevisionStrategy;
-	private final Set<Capability> capabilities;
 	private DeliberationFunction deliberationFunction;
 	private final List<Intention> intentions;
 	private OptionGenerationFunction optionGenerationFunction;
 	private PlanSelectionStrategy planSelectionStrategy;
+	private final Capability rootCapability;
+	private final Set<Softgoal> softgoals;
 
 	/**
 	 * Default constructor.
 	 */
 	public BDIAgent() {
-		this.capabilities = new HashSet<Capability>();
+		this.rootCapability = new Capability();
 		this.intentions = new LinkedList<Intention>();
+		this.softgoals = new HashSet<Softgoal>();
 		this.bdiInterpreter = new BDIInterpreter(this);
 		this.beliefRevisionStrategy = new DefaultBeliefRevisionStrategy();
 		this.optionGenerationFunction = new DefaultOptionGenerationFunction();
@@ -211,9 +214,14 @@ public class BDIAgent extends Agent {
 	 *            capability to be added.
 	 */
 	public void addCapability(Capability capability) {
-		synchronized (capabilities) {
+		synchronized (rootCapability) {
+			if (capability.getParent() != null) {
+				throw new RuntimeException(
+						"Capability already binded to another capability!");
+			}
+
+			this.rootCapability.addChild(capability);
 			capability.setMyAgent(this);
-			this.capabilities.add(capability);
 		}
 	}
 
@@ -248,8 +256,18 @@ public class BDIAgent extends Agent {
 	}
 
 	/**
+	 * Adds a new softgoal to this agent.
+	 * 
+	 * @param softgoal
+	 *            the softgoal to be pursued.
+	 */
+	public void addSoftgoal(Softgoal softgoal) {
+		this.softgoals.add(softgoal);
+	}
+
+	/**
 	 * Drops a given goal of this agent. If the goal is not part of the agent's
-	 * current goal, no action is performed.
+	 * current goals, no action is performed.
 	 * 
 	 * @param goal
 	 *            the goal to be dropped.
@@ -266,25 +284,59 @@ public class BDIAgent extends Agent {
 	}
 
 	/**
+	 * Drops a given softgoal of this agent. If the softgoal is not part of the
+	 * agent's current softgoals, no action is performed.
+	 * 
+	 * @param softgoal
+	 *            the softgoal to be dropped.
+	 */
+
+	public void dropSoftoal(Softgoal softgoal) {
+		this.softgoals.remove(softgoal);
+	}
+
+	/**
 	 * Returns a collection of all beliefs from all capabilities of this agent.
 	 * It may have two equivalent beliefs, i.e. beliefs with the same name.
 	 * 
 	 * @return the collection of all beliefs of this agent.
 	 */
 	public Collection<Belief<?>> getAllBeliefs() {
-		synchronized (capabilities) {
-			int size = 0;
-			for (Capability capability : capabilities) {
-				size += capability.getBeliefBase().size();
-			}
-			Collection<Belief<?>> beliefs = new ArrayList<Belief<?>>(size);
-			for (Capability capability : capabilities) {
-				beliefs.addAll(capability.getBeliefBase().getBeliefs());
-			}
+		synchronized (rootCapability) {
+			Collection<Belief<?>> beliefs = new LinkedList<Belief<?>>();
+			getAllBeliefs(beliefs, rootCapability);
 			return beliefs;
 		}
 	}
 
+	private void getAllBeliefs(final Collection<Belief<?>> beliefs,
+			Capability capability) {
+		beliefs.addAll(capability.getBeliefBase().getBeliefs());
+		for (Capability child : capability.getChildren()) {
+			getAllBeliefs(beliefs, child);
+		}
+	}
+
+	/**
+	 * @return the capabilities
+	 */
+	public List<Capability> getAllCapabilities() {
+		synchronized (rootCapability) {
+			List<Capability> capabilities = new ArrayList<>();
+			getAllCapabilities(capabilities, rootCapability);
+			return capabilities;
+		}
+	}
+
+	private void getAllCapabilities(final List<Capability> capabilities,
+			Capability capability) {
+		capabilities.add(capability);
+		Set<Capability> children = capability.getChildren();
+		for (Capability child : children) {
+			getAllCapabilities(capabilities, child);
+		}
+	}
+
 	/**
 	 * Gets all goals of this agent. This goals are the ones in the goal set and
 	 * the ones that are trying to be achieve in intentions.
@@ -302,19 +354,19 @@ public class BDIAgent extends Agent {
 	}
 
 	/**
-	 * @return the beliefRevisionStrategy
+	 * Gets all softgoals of this agent.
+	 * 
+	 * @return the set of softgoals.
 	 */
-	public BeliefRevisionStrategy getBeliefRevisionStrategy() {
-		return beliefRevisionStrategy;
+	public Set<Softgoal> getAllSoftgoals() {
+		return this.softgoals;
 	}
 
 	/**
-	 * @return the capabilities
+	 * @return the beliefRevisionStrategy
 	 */
-	public Set<Capability> getCapabilities() {
-		synchronized (capabilities) {
-			return capabilities;
-		}
+	public BeliefRevisionStrategy getBeliefRevisionStrategy() {
+		return beliefRevisionStrategy;
 	}
 
 	/**
@@ -353,6 +405,15 @@ public class BDIAgent extends Agent {
 	}
 
 	/**
+	 * Returns the root capability of this agent.
+	 * 
+	 * @return the rootCapability
+	 */
+	public Capability getRootCapability() {
+		return rootCapability;
+	}
+
+	/**
 	 * This method initializes the BDI agent. It is invoked by the
 	 * {@link #setup()} method.
 	 */
@@ -369,8 +430,8 @@ public class BDIAgent extends Agent {
 	 * @return true if the capability exists and was removed.
 	 */
 	public boolean removeCapability(Capability capability) {
-		synchronized (capabilities) {
-			boolean removed = this.capabilities.remove(capability);
+		synchronized (rootCapability) {
+			boolean removed = this.rootCapability.removeChild(capability);
 			if (removed) {
 				capability.setMyAgent(null);
 			}
@@ -468,9 +529,13 @@ public class BDIAgent extends Agent {
 	 */
 	@Override
 	protected void takeDown() {
-		while (!capabilities.isEmpty()) {
-			this.removeCapability(capabilities.iterator().next());
+		synchronized (rootCapability) {
+			Set<Capability> capabilities = rootCapability.getChildren();
+			for (Capability capability : capabilities) {
+				rootCapability.removeChild(capability);
+			}
 		}
+
 	}
 
 }
diff --git a/bdi-jade/src/br/ufrgs/inf/bdi4jade/core/BeliefBase.java b/bdi-jade/src/br/ufrgs/inf/bdi4jade/core/BeliefBase.java
index c1f2706..9074ba3 100644
--- a/bdi-jade/src/br/ufrgs/inf/bdi4jade/core/BeliefBase.java
+++ b/bdi-jade/src/br/ufrgs/inf/bdi4jade/core/BeliefBase.java
@@ -24,16 +24,18 @@ package br.ufrgs.inf.bdi4jade.core;
 
 import java.io.Serializable;
 import java.util.ArrayList;
+import java.util.Collection;
 import java.util.HashMap;
 import java.util.HashSet;
+import java.util.LinkedList;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
 
 import br.ufrgs.inf.bdi4jade.belief.Belief;
 import br.ufrgs.inf.bdi4jade.event.BeliefEvent;
-import br.ufrgs.inf.bdi4jade.event.BeliefListener;
 import br.ufrgs.inf.bdi4jade.event.BeliefEvent.Action;
+import br.ufrgs.inf.bdi4jade.event.BeliefListener;
 import br.ufrgs.inf.bdi4jade.exception.BeliefAlreadyExistsException;
 
 /**
@@ -117,14 +119,40 @@ public class BeliefBase implements Serializable {
 	}
 
 	/**
-	 * Retrieves a belief from the belief base.
+	 * Gets all beliefs of this belief base and the belief bases of the parents
+	 * of the capability that this belief base belongs to.
+	 * 
+	 * @return the beliefs
+	 */
+	public Collection<Belief<?>> getAllBeliefs() {
+		Collection<Belief<?>> beliefs = new LinkedList<Belief<?>>();
+		getAllBeliefs(beliefs);
+		return beliefs;
+	}
+
+	private void getAllBeliefs(final Collection<Belief<?>> beliefs) {
+		beliefs.addAll(this.beliefs.values());
+		if (capability != null && capability.getParent() != null) {
+			capability.getParent().getBeliefBase().getAllBeliefs(beliefs);
+		}
+	}
+
+	/**
+	 * Retrieves a belief from the belief base. If this belief does not contain
+	 * it and this belief base is from a capability, it checks the common belief
+	 * based of the agent, and returns it if it exists.
 	 * 
 	 * @param name
 	 *            the name of the belief to be retrieved.
 	 * @return the belief. Null if no belief is found.
 	 */
 	public Belief<?> getBelief(String name) {
-		return this.beliefs.get(name);
+		Belief<?> belief = this.beliefs.get(name);
+		if (belief == null && capability != null
+				&& capability.getParent() != null) {
+			belief = capability.getParent().getBeliefBase().getBelief(name);
+		}
+		return belief;
 	}
 
 	/**
@@ -135,6 +163,8 @@ public class BeliefBase implements Serializable {
 	}
 
 	/**
+	 * Gets all beliefs of this belief base.
+	 * 
 	 * @return the beliefs
 	 */
 	public Set<Belief<?>> getBeliefs() {
@@ -171,7 +201,11 @@ public class BeliefBase implements Serializable {
 	 * @return true if the belief base contains the belief.
 	 */
 	public boolean hasBelief(String name) {
-		return this.beliefs.containsKey(name);
+		boolean hasBelief = this.beliefs.containsKey(name);
+		if (!hasBelief && capability != null && capability.getParent() != null) {
+			hasBelief = capability.getParent().getBeliefBase().hasBelief(name);
+		}
+		return hasBelief;
 	}
 
 	/**
@@ -191,6 +225,11 @@ public class BeliefBase implements Serializable {
 		for (BeliefListener beliefListener : beliefListeners) {
 			beliefListener.update(beliefChanged);
 		}
+		if (capability != null) {
+			for (Capability child : capability.getChildren()) {
+				child.getBeliefBase().notifyBeliefChanged(beliefChanged);
+			}
+		}
 	}
 
 	/**
@@ -206,6 +245,11 @@ public class BeliefBase implements Serializable {
 		if (belief != null) {
 			belief.removeBeliefBase(this);
 			notifyBeliefChanged(new BeliefEvent(belief, Action.BELIEF_REMOVED));
+		} else {
+			if (capability != null && capability.getParent() != null) {
+				belief = capability.getParent().getBeliefBase()
+						.removeBelief(name);
+			}
 		}
 		return belief;
 	}
@@ -278,14 +322,19 @@ public class BeliefBase implements Serializable {
 	@SuppressWarnings("unchecked")
 	public boolean updateBelief(String name, Object value) {
 		Belief belief = this.beliefs.get(name);
-		if (belief == null) {
-			return false;
+
+		if (belief != null) {
+			Object oldValue = belief.getValue();
+			belief.setValue(value);
+			notifyBeliefChanged(new BeliefEvent(belief, Action.BELIEF_UPDATED,
+					oldValue));
+			return true;
+		} else if (capability != null && capability.getParent() != null) {
+			return capability.getParent().getBeliefBase()
+					.updateBelief(name, value);
 		}
-		Object oldValue = belief.getValue();
-		belief.setValue(value);
-		notifyBeliefChanged(new BeliefEvent(belief, Action.BELIEF_UPDATED,
-				oldValue));
-		return true;
+
+		return false;
 	}
 
 }
diff --git a/bdi-jade/src/br/ufrgs/inf/bdi4jade/core/Capability.java b/bdi-jade/src/br/ufrgs/inf/bdi4jade/core/Capability.java
index 0ec80bb..655a77a 100644
--- a/bdi-jade/src/br/ufrgs/inf/bdi4jade/core/Capability.java
+++ b/bdi-jade/src/br/ufrgs/inf/bdi4jade/core/Capability.java
@@ -22,14 +22,16 @@
 
 package br.ufrgs.inf.bdi4jade.core;
 
-import java.io.Serializable;
-
 import jade.lang.acl.ACLMessage;
 
+import java.io.Serializable;
+import java.util.HashSet;
+import java.util.Set;
+
 /**
  * This capability represents a component that aggregates the mental attitudes
  * defined by the BDI architecture. It has a belief base with the associated
- * beliefs (knowledge) and a plan library. *
+ * beliefs (knowledge) and a plan library.
  * 
  * @author ingrid
  */
@@ -38,8 +40,10 @@ public class Capability implements Serializable {
 	private static final long serialVersionUID = -4922359927943108421L;
 
 	protected final BeliefBase beliefBase;
+	protected final Set<Capability> children;
 	protected final String id;
 	protected BDIAgent myAgent;
+	protected Capability parent;
 	protected final PlanLibrary planLibrary;
 	private boolean start;
 
@@ -50,7 +54,7 @@ public class Capability implements Serializable {
 	public Capability() {
 		this(null);
 	}
-	
+
 	/**
 	 * Creates a new capability.
 	 * 
@@ -59,8 +63,7 @@ public class Capability implements Serializable {
 	 * @param planLibrary
 	 *            the plan library of this capability.
 	 */
-	public Capability(BeliefBase beliefBase,
-			PlanLibrary planLibrary) {
+	public Capability(BeliefBase beliefBase, PlanLibrary planLibrary) {
 		this(null, beliefBase, planLibrary);
 	}
 
@@ -87,7 +90,38 @@ public class Capability implements Serializable {
 	 * @param planLibrary
 	 *            the plan library of this capability.
 	 */
-	public Capability(String id, BeliefBase beliefBase,
+	public Capability(String id, BeliefBase beliefBase, PlanLibrary planLibrary) {
+		this(id, null, beliefBase, planLibrary);
+	}
+
+	/**
+	 * Creates a new capability. It uses {@link BeliefBase} and
+	 * {@link PlanLibrary} as belief base and plan library respectively.
+	 * 
+	 * @param id
+	 *            the capability id. If it is null, the class name is going to
+	 *            be used.
+	 * @param parent
+	 *            the parent of this capability.
+	 */
+	public Capability(String id, Capability parent) {
+		this(id, parent, new BeliefBase(), new PlanLibrary());
+	}
+
+	/**
+	 * Creates a new capability.
+	 * 
+	 * @param id
+	 *            the capability id. If it is null, the class name is going to
+	 *            be used.
+	 * @param parent
+	 *            the parent of this capability.
+	 * @param beliefBase
+	 *            the belief base of this capability.
+	 * @param planLibrary
+	 *            the plan library of this capability.
+	 */
+	public Capability(String id, Capability parent, BeliefBase beliefBase,
 			PlanLibrary planLibrary) {
 		if (id == null) {
 			if (this.getClass().getCanonicalName() == null
@@ -100,6 +134,10 @@ public class Capability implements Serializable {
 		} else {
 			this.id = id;
 		}
+		this.children = new HashSet<>();
+		if (parent != null) {
+			parent.addChild(this);
+		}
 		beliefBase.setCapability(this);
 		this.beliefBase = beliefBase;
 		planLibrary.setCapability(this);
@@ -107,6 +145,14 @@ public class Capability implements Serializable {
 		this.start = false;
 	}
 
+	public void addChild(Capability capability) {
+		if (capability.parent != null) {
+			capability.parent.removeChild(capability);
+		}
+		capability.parent = this;
+		this.children.add(capability);
+	}
+
 	/**
 	 * Checks if this capability has a plan that can process the given message.
 	 * 
@@ -127,6 +173,13 @@ public class Capability implements Serializable {
 	}
 
 	/**
+	 * @return the children
+	 */
+	public Set<Capability> getChildren() {
+		return new HashSet<>(children);
+	}
+
+	/**
 	 * @return the id
 	 */
 	public String getId() {
@@ -141,14 +194,34 @@ public class Capability implements Serializable {
 	}
 
 	/**
+	 * @return the parent
+	 */
+	public Capability getParent() {
+		return parent;
+	}
+
+	/**
 	 * @return the planLibrary
 	 */
 	public PlanLibrary getPlanLibrary() {
 		return planLibrary;
 	}
 
+	public boolean hasChildren() {
+		return !this.children.isEmpty();
+	}
+
+	public boolean removeChild(Capability capability) {
+		boolean removed = this.children.remove(capability);
+		if (removed) {
+			capability.parent = null;
+		}
+		return removed;
+	}
+
 	/**
-	 * @param myAgent the myAgent to set
+	 * @param myAgent
+	 *            the myAgent to set
 	 */
 	public void setMyAgent(BDIAgent myAgent) {
 		this.myAgent = myAgent;
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 581218e..029e149 100644
--- a/bdi-jade/src/br/ufrgs/inf/bdi4jade/core/Intention.java
+++ b/bdi-jade/src/br/ufrgs/inf/bdi4jade/core/Intention.java
@@ -166,6 +166,9 @@ public class Intention {
 			this.executedPlans.add(this.currentPlan.getPlan());
 			this.currentPlan = null;
 			break;
+		default:
+			assert false : status;
+			break;
 		}
 	}
 
@@ -201,12 +204,17 @@ public class Intention {
 	 */
 	private Set<Plan> getCanAchievePlans() {
 		Set<Plan> plans = new HashSet<Plan>();
-		for (Capability capability : myAgent.getCapabilities()) {
-			plans.addAll(capability.getPlanLibrary().canAchievePlans(goal));
-		}
+		getCanAchievePlans(plans, myAgent.getRootCapability());
 		return plans;
 	}
 
+	private void getCanAchievePlans(final Set<Plan> plans, Capability capability) {
+		plans.addAll(capability.getPlanLibrary().canAchievePlans(goal));
+		for (Capability child : capability.getChildren()) {
+			getCanAchievePlans(plans, child);
+		}
+	}
+
 	/**
 	 * @return the goal
 	 */
@@ -279,6 +287,9 @@ public class Intention {
 			this.executedPlans.add(this.currentPlan.getPlan());
 			this.currentPlan = null;
 			break;
+		default:
+			assert false : status;
+			break;
 		}
 	}
 
@@ -314,6 +325,9 @@ public class Intention {
 			this.currentPlan = null;
 			dispatchPlan();
 			break;
+		default:
+			assert false : status;
+			break;
 		}
 	}
 
diff --git a/bdi-jade/src/br/ufrgs/inf/bdi4jade/message/BDIAgentMsgReceiver.java b/bdi-jade/src/br/ufrgs/inf/bdi4jade/message/BDIAgentMsgReceiver.java
index 259cd01..35f6f1d 100644
--- a/bdi-jade/src/br/ufrgs/inf/bdi4jade/message/BDIAgentMsgReceiver.java
+++ b/bdi-jade/src/br/ufrgs/inf/bdi4jade/message/BDIAgentMsgReceiver.java
@@ -51,16 +51,21 @@ public class BDIAgentMsgReceiver extends MsgReceiver {
 
 		private BDIAgentMsgReceiver bdiAgentMsgReceiver;
 
+		private void getCanProcessCapabilities(final ACLMessage msg,
+				final Set<Capability> capabilities, Capability capability) {
+			if (capability.canProcess(msg)) {
+				capabilities.add(capability);
+			}
+			for (Capability child : capability.getChildren()) {
+				getCanProcessCapabilities(msg, capabilities, child);
+			}
+		}
+
 		@Override
 		public boolean match(ACLMessage msg) {
 			Set<Capability> capabilities = new HashSet<Capability>();
-
-			for (Capability capability : bdiAgentMsgReceiver.getMyAgent()
-					.getCapabilities()) {
-				if (capability.canProcess(msg)) {
-					capabilities.add(capability);
-				}
-			}
+			getCanProcessCapabilities(msg, capabilities, bdiAgentMsgReceiver
+					.getMyAgent().getRootCapability());
 
 			if (!capabilities.isEmpty()) {
 				bdiAgentMsgReceiver.messageMatched(msg, capabilities);
diff --git a/bdi-jade/src/br/ufrgs/inf/bdi4jade/preference/SoftgoalPreferences.java b/bdi-jade/src/br/ufrgs/inf/bdi4jade/preference/SoftgoalPreferences.java
new file mode 100644
index 0000000..fb5c521
--- /dev/null
+++ b/bdi-jade/src/br/ufrgs/inf/bdi4jade/preference/SoftgoalPreferences.java
@@ -0,0 +1,70 @@
+//----------------------------------------------------------------------------
+// Copyright (C) 2013  Ingrid Nunes, et al.
+// 
+// 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 br.ufrgs.inf.bdi4jade.preference;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import br.ufrgs.inf.bdi4jade.belief.TransientBelief;
+import br.ufrgs.inf.bdi4jade.softgoal.Softgoal;
+
+/**
+ * This is an agent transient belief (@see {@link TransientBelief}) that stores
+ * the preferences for softgoals.
+ * 
+ * @author ingrid
+ */
+public class SoftgoalPreferences extends TransientBelief<Map<Softgoal, Double>> {
+
+	public static final String NAME = SoftgoalPreferences.class.getSimpleName();
+
+	private static final long serialVersionUID = 1802540697397519283L;
+
+	public SoftgoalPreferences() {
+		super(NAME, new HashMap<Softgoal, Double>());
+	}
+
+	/**
+	 * Returns the preference for a softgoal.
+	 * 
+	 * @param softgoal
+	 *            the softgoal
+	 * @return the preference for the softgoal
+	 */
+	public Double getPreferenceForSoftgoal(Softgoal softgoal) {
+		return this.value.get(softgoal);
+	}
+
+	/**
+	 * Sets the preference for a softgoal.
+	 * 
+	 * @param softgoal
+	 *            the softgoal to which the preference is set.
+	 * @param preference
+	 *            the preference value.
+	 */
+	public void setPreferenceForSoftgoal(Softgoal softgoal, Double preference) {
+		this.value.put(softgoal, preference);
+	}
+
+}
diff --git a/bdi-jade/src/br/ufrgs/inf/bdi4jade/util/agent/UtilityBasedBDIAgent.java b/bdi-jade/src/br/ufrgs/inf/bdi4jade/util/agent/UtilityBasedBDIAgent.java
new file mode 100644
index 0000000..76e6213
--- /dev/null
+++ b/bdi-jade/src/br/ufrgs/inf/bdi4jade/util/agent/UtilityBasedBDIAgent.java
@@ -0,0 +1,43 @@
+//----------------------------------------------------------------------------
+// Copyright (C) 2013  Ingrid Nunes, et al.
+// 
+// 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 br.ufrgs.inf.bdi4jade.util.agent;
+
+import br.ufrgs.inf.bdi4jade.core.BDIAgent;
+import br.ufrgs.inf.bdi4jade.preference.SoftgoalPreferences;
+import br.ufrgs.inf.bdi4jade.util.reasoning.UtilityBasedPlanSelectionStrategy;
+
+/**
+ * @author ingrid
+ * 
+ */
+public class UtilityBasedBDIAgent extends BDIAgent {
+
+	private static final long serialVersionUID = -1721751203235905764L;
+
+	public UtilityBasedBDIAgent() {
+		setPlanSelectionStrategy(new UtilityBasedPlanSelectionStrategy(this));
+		getRootCapability().getBeliefBase()
+				.addBelief(new SoftgoalPreferences());
+	}
+
+}
diff --git a/bdi-jade/src/br/ufrgs/inf/bdi4jade/util/reasoning/DefaultBeliefRevisionStrategy.java b/bdi-jade/src/br/ufrgs/inf/bdi4jade/util/reasoning/DefaultBeliefRevisionStrategy.java
index ee8f61c..3a58972 100644
--- a/bdi-jade/src/br/ufrgs/inf/bdi4jade/util/reasoning/DefaultBeliefRevisionStrategy.java
+++ b/bdi-jade/src/br/ufrgs/inf/bdi4jade/util/reasoning/DefaultBeliefRevisionStrategy.java
@@ -44,8 +44,13 @@ public class DefaultBeliefRevisionStrategy implements BeliefRevisionStrategy {
 	 */
 	@Override
 	public void reviewBeliefs(BDIAgent bdiAgent) {
-		for (Capability capability : bdiAgent.getCapabilities()) {
-			capability.getBeliefBase().reviewBeliefs();
+		reviewBeliefs(bdiAgent.getRootCapability());
+	}
+
+	public void reviewBeliefs(Capability capability) {
+		capability.getBeliefBase().reviewBeliefs();
+		for (Capability child : capability.getChildren()) {
+			reviewBeliefs(child);
 		}
 	}
 
diff --git a/bdi-jade/src/br/ufrgs/inf/bdi4jade/util/reasoning/UtilityBasedPlanSelectionStrategy.java b/bdi-jade/src/br/ufrgs/inf/bdi4jade/util/reasoning/UtilityBasedPlanSelectionStrategy.java
index 4637f78..c7fe22a 100644
--- a/bdi-jade/src/br/ufrgs/inf/bdi4jade/util/reasoning/UtilityBasedPlanSelectionStrategy.java
+++ b/bdi-jade/src/br/ufrgs/inf/bdi4jade/util/reasoning/UtilityBasedPlanSelectionStrategy.java
@@ -22,11 +22,16 @@
 
 package br.ufrgs.inf.bdi4jade.util.reasoning;
 
+import java.util.List;
 import java.util.Set;
 
+import br.ufrgs.inf.bdi4jade.core.BDIAgent;
 import br.ufrgs.inf.bdi4jade.goal.Goal;
 import br.ufrgs.inf.bdi4jade.plan.Plan;
+import br.ufrgs.inf.bdi4jade.plan.PlanContribution;
+import br.ufrgs.inf.bdi4jade.preference.SoftgoalPreferences;
 import br.ufrgs.inf.bdi4jade.reasoning.PlanSelectionStrategy;
+import br.ufrgs.inf.bdi4jade.softgoal.Softgoal;
 
 /**
  * A utility-based implementation of the {@link PlanSelectionStrategy}. It
@@ -37,16 +42,68 @@ import br.ufrgs.inf.bdi4jade.reasoning.PlanSelectionStrategy;
  */
 public class UtilityBasedPlanSelectionStrategy implements PlanSelectionStrategy {
 
+	private final BDIAgent myAgent;
+
+	public UtilityBasedPlanSelectionStrategy(BDIAgent myAgent) {
+		this.myAgent = myAgent;
+	}
+
+	@SuppressWarnings("unchecked")
+	private double calculateExpectedUtility(Plan plan, Softgoal softgoal) {
+		List<PlanContribution> contributions = (List<PlanContribution>) plan
+				.getMetadata(Plan.DefaultMetadata.CONTRIBUTIONS);
+
+		double expectedUtility = 0;
+		if (contributions != null) {
+			for (PlanContribution contribution : contributions) {
+				expectedUtility += contribution.getProbability()
+						* contribution.getValue();
+			}
+		}
+		return expectedUtility;
+	}
+
+	/**
+	 * @return the myAgent
+	 */
+	public BDIAgent getMyAgent() {
+		return myAgent;
+	}
+
 	/**
 	 * @see br.ufrgs.inf.bdi4jade.reasoning.PlanSelectionStrategy#selectPlan(br.ufrgs.inf.bdi4jade.goal.Goal,
 	 *      java.util.Set)
 	 */
 	@Override
 	public Plan selectPlan(Goal goal, Set<Plan> plans) {
-		if (plans.isEmpty())
-			return null;
-		else
-			return plans.iterator().next();
+		Plan selectedPlan = null;
+		Double maxUtility = null;
+
+		for (Plan plan : plans) {
+			double utility = 0;
+
+			SoftgoalPreferences preferences = (SoftgoalPreferences) plan
+					.getPlanLibrary().getCapability().getBeliefBase()
+					.getBelief(SoftgoalPreferences.NAME);
+
+			for (Softgoal softgoal : myAgent.getAllSoftgoals()) {
+				Double preference = preferences
+						.getPreferenceForSoftgoal(softgoal);
+				if (preference != null) {
+
+					double expectedUtility = calculateExpectedUtility(plan,
+							softgoal);
+					utility += preference * expectedUtility;
+
+				}
+			}
+			if (selectedPlan == null || maxUtility < utility) {
+				selectedPlan = plan;
+				maxUtility = utility;
+			}
+		}
+
+		return selectedPlan;
 	}
 
 }
diff --git a/bdi-jade/src/log4j.properties b/bdi-jade/src/log4j.properties
index bb6e3a6..1a4ee8a 100644
--- a/bdi-jade/src/log4j.properties
+++ b/bdi-jade/src/log4j.properties
@@ -29,6 +29,6 @@ log4j.logger.org.apache.struts2=FATAL
 # Spring Stuff
 log4j.logger.org.springframework=FATAL
 
-log4j.logger.br.ufrgs.inf.bdi4jade=DEBUG
+log4j.logger.br.ufrgs.inf.bdi4jade=INFO
 log4j.logger.br.ufrgs.inf.bdi4jade.examples=DEBUG
 
diff --git a/bdi-jade-test/src/br/ufrgs/inf/bdi4jade/examples/BDIAgent1.java b/bdi-jade-test/src/br/ufrgs/inf/bdi4jade/examples/BDIAgent1.java
index 3276d2b..2a715af 100644
--- a/bdi-jade-test/src/br/ufrgs/inf/bdi4jade/examples/BDIAgent1.java
+++ b/bdi-jade-test/src/br/ufrgs/inf/bdi4jade/examples/BDIAgent1.java
@@ -23,7 +23,7 @@
 package br.ufrgs.inf.bdi4jade.examples;
 
 import br.ufrgs.inf.bdi4jade.core.BDIAgent;
-import br.ufrgs.inf.bdi4jade.examples.compositegoal.CompositeGoalCapability;
+import br.ufrgs.inf.bdi4jade.examples.blocksworld.BlocksWorldCapability;
 
 /**
  * @author ingrid
@@ -36,13 +36,13 @@ public class BDIAgent1 extends BDIAgent {
 
 	@Override
 	protected void init() {
-		// this.addCapability(new BlocksWorldCapability());
+		this.addCapability(new BlocksWorldCapability());
 		// this.addCapability(new PlanFailedCapability());
 		// this.addCapability(new SubgoalCapability());
 		// this.addCapability(new PingPongCapability(BDIAgent1.MY_NAME,
 		// BDIAgent2.MY_NAME));
 		// this.addCapability(new CompositeGoalCapability(true));
-		this.addCapability(new CompositeGoalCapability(false));
+		// this.addCapability(new CompositeGoalCapability(false));
 	}
 
 }
diff --git a/bdi-jade-test/src/br/ufrgs/inf/bdi4jade/examples/helloworld/HelloWorldAgent.java b/bdi-jade-test/src/br/ufrgs/inf/bdi4jade/examples/helloworld/HelloWorldAgent.java
index 7296541..7580a69 100644
--- a/bdi-jade-test/src/br/ufrgs/inf/bdi4jade/examples/helloworld/HelloWorldAgent.java
+++ b/bdi-jade-test/src/br/ufrgs/inf/bdi4jade/examples/helloworld/HelloWorldAgent.java
@@ -4,10 +4,25 @@
 package br.ufrgs.inf.bdi4jade.examples.helloworld;
 
 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;
 
+public class HelloWorldAgent extends BDIAgent {
+
+	private static final long serialVersionUID = 2712019445290687786L;
+
+	protected void init() {
+		this.getRootCapability()
+				.getPlanLibrary()
+				.addPlan(
+						new SimplePlan(HelloWorldGoal.class,
+								HelloWorldPlan.class));
+
+		addGoal(new HelloWorldGoal("reader"));
+	}
+
+}
+
 /**
  * @author ingridn
  * 
@@ -26,24 +41,3 @@ class HelloWorldGoal implements Goal {
 		return name;
 	}
 }
-
-public class HelloWorldAgent extends BDIAgent {
-
-	private static final long serialVersionUID = 2712019445290687786L;
-
-	protected void init() {
-		addCapability(new Capability() {
-
-			private static final long serialVersionUID = 5271907167861942067L;
-
-			protected void setup() {
-				getPlanLibrary().addPlan(
-						new SimplePlan(HelloWorldGoal.class,
-								HelloWorldPlan.class));
-			}
-
-		});
-
-		addGoal(new HelloWorldGoal("reader"));
-	}
-}