bdi4jade

Belief goal plan

4/7/2014 11:10:07 PM

Details

diff --git a/bdi-jade/src/bdi4jade/plan/AbstractPlan.java b/bdi-jade/src/bdi4jade/plan/AbstractPlan.java
index 3bb155c..3ecf93e 100644
--- a/bdi-jade/src/bdi4jade/plan/AbstractPlan.java
+++ b/bdi-jade/src/bdi4jade/plan/AbstractPlan.java
@@ -197,6 +197,13 @@ public abstract class AbstractPlan extends MetadataElementImpl implements Plan {
 	}
 
 	/**
+	 * @return the goals
+	 */
+	public Set<Class<? extends Goal>> getGoals() {
+		return goals;
+	}
+
+	/**
 	 * @return the id
 	 */
 	public String getId() {
@@ -204,6 +211,13 @@ public abstract class AbstractPlan extends MetadataElementImpl implements Plan {
 	}
 
 	/**
+	 * @return the messageTemplates
+	 */
+	public Set<MessageTemplate> getMessageTemplates() {
+		return messageTemplates;
+	}
+
+	/**
 	 * @return the planLibrary
 	 */
 	public PlanLibrary getPlanLibrary() {
diff --git a/bdi-jade/src/bdi4jade/util/goal/BeliefSetValueGoal.java b/bdi-jade/src/bdi4jade/util/goal/BeliefSetValueGoal.java
index 1ea958b..70a04df 100644
--- a/bdi-jade/src/bdi4jade/util/goal/BeliefSetValueGoal.java
+++ b/bdi-jade/src/bdi4jade/util/goal/BeliefSetValueGoal.java
@@ -24,7 +24,6 @@ package bdi4jade.util.goal;
 
 import bdi4jade.belief.BeliefSet;
 import bdi4jade.core.BeliefBase;
-import bdi4jade.goal.Goal;
 
 /**
  * This class represents the goal of an agent believe in a belief that contains
@@ -33,13 +32,10 @@ import bdi4jade.goal.Goal;
  * 
  * @author ingrid
  */
-public class BeliefSetValueGoal<T> implements Goal {
+public class BeliefSetValueGoal<T> extends BeliefValueGoal<T> {
 
 	private static final long serialVersionUID = 2493877854717226283L;
 
-	private String beliefSetName;
-	private T value;
-
 	/**
 	 * Creates a new BeliefSetValueGoal with the provided belief name and a
 	 * value. This value represents the one that should be part of the belief
@@ -51,22 +47,7 @@ public class BeliefSetValueGoal<T> implements Goal {
 	 *            the value that is target of this goal.
 	 */
 	public BeliefSetValueGoal(String beliefSetName, T value) {
-		this.beliefSetName = beliefSetName;
-		this.value = value;
-	}
-
-	/**
-	 * @return the beliefSetName
-	 */
-	public String getBeliefSetName() {
-		return beliefSetName;
-	}
-
-	/**
-	 * @return the value
-	 */
-	public T getValue() {
-		return value;
+		super(beliefSetName, value);
 	}
 
 	/**
@@ -80,20 +61,12 @@ public class BeliefSetValueGoal<T> implements Goal {
 	@SuppressWarnings("unchecked")
 	public boolean isAchieved(BeliefBase beliefBase) {
 		BeliefSet<T> beliefSet = (BeliefSet<T>) beliefBase
-				.getBelief(beliefSetName);
+				.getBelief(getBeliefName());
 		if (beliefSet == null) {
 			return false;
 		} else {
-			return beliefSet.hasValue(value);
+			return beliefSet.hasValue(getValue());
 		}
 	}
 
-	/**
-	 * @see java.lang.Object#toString()
-	 */
-	@Override
-	public String toString() {
-		return "Belief '" + beliefSetName + "' has value " + value;
-	}
-
 }
diff --git a/bdi-jade/src/bdi4jade/util/goal/BeliefValueGoal.java b/bdi-jade/src/bdi4jade/util/goal/BeliefValueGoal.java
new file mode 100644
index 0000000..29dfe06
--- /dev/null
+++ b/bdi-jade/src/bdi4jade/util/goal/BeliefValueGoal.java
@@ -0,0 +1,86 @@
+//----------------------------------------------------------------------------
+// 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.util.goal;
+
+import bdi4jade.belief.Belief;
+import bdi4jade.core.BeliefBase;
+
+/**
+ * @author ingrid
+ * 
+ */
+public class BeliefValueGoal<T> extends BeliefGoal {
+
+	private static final long serialVersionUID = 2493877854717226283L;
+
+	private T value;
+
+	/**
+	 * Creates a new BeliefSetValueGoal with the provided belief name and a
+	 * value. This value represents the one that should be part of the belief
+	 * set.
+	 * 
+	 * @param beliefName
+	 *            the belief name.
+	 * @param value
+	 *            the value that is target of this goal.
+	 */
+	public BeliefValueGoal(String beliefName, T value) {
+		super(beliefName);
+		this.value = value;
+	}
+
+	/**
+	 * @return the value
+	 */
+	public T getValue() {
+		return value;
+	}
+
+	/**
+	 * Checks if this goal is achieved by verifying if the provided belief set
+	 * contains the Value of this goal.
+	 * 
+	 * @param beliefBase
+	 *            the belief base to be checked.
+	 * @return true if the belief sey contains the value of this goal.
+	 */
+	@SuppressWarnings("unchecked")
+	public boolean isAchieved(BeliefBase beliefBase) {
+		Belief<T> belief = (Belief<T>) beliefBase.getBelief(getBeliefName());
+		if (belief == null) {
+			return false;
+		} else {
+			return belief.getValue().equals(value);
+		}
+	}
+
+	/**
+	 * @see java.lang.Object#toString()
+	 */
+	@Override
+	public String toString() {
+		return "Belief '" + getBeliefName() + "' has value " + value;
+	}
+
+}
\ No newline at end of file
diff --git a/bdi-jade/src/bdi4jade/util/plan/BeliefGoalPlan.java b/bdi-jade/src/bdi4jade/util/plan/BeliefGoalPlan.java
new file mode 100644
index 0000000..743dbbc
--- /dev/null
+++ b/bdi-jade/src/bdi4jade/util/plan/BeliefGoalPlan.java
@@ -0,0 +1,111 @@
+//----------------------------------------------------------------------------
+// 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.util.plan;
+
+import jade.lang.acl.ACLMessage;
+import bdi4jade.goal.Goal;
+import bdi4jade.message.MessageGoal;
+import bdi4jade.plan.AbstractPlan;
+import bdi4jade.plan.SimplePlan;
+import bdi4jade.util.goal.BeliefGoal;
+
+/**
+ * @author ingrid
+ * 
+ */
+public class BeliefGoalPlan extends SimplePlan {
+
+	private final String beliefName;
+
+	protected BeliefGoalPlan(Class<? extends BeliefGoal> beliefGoalClass,
+			String beliefName, Class<? extends BeliefGoalPlanBody> planBodyClass) {
+		super(beliefGoalClass, planBodyClass);
+		this.beliefName = beliefName;
+	}
+
+	protected BeliefGoalPlan(String id,
+			Class<? extends BeliefGoal> beliefGoalClass, String beliefName,
+			Class<? extends BeliefGoalPlanBody> planBodyClass) {
+		super(id, beliefGoalClass, planBodyClass);
+		this.beliefName = beliefName;
+	}
+
+	/**
+	 * Constructs a new Plan. It sets the plan library and plan body class of
+	 * this plan, and initializes the goals that it can achieve and messages it
+	 * can process. The goals are initialized with the provided goal class.
+	 * 
+	 * @param id
+	 *            plan identifier
+	 * @param goalClass
+	 *            the goal that this plan can achieve
+	 */
+	public BeliefGoalPlan(String beliefName,
+			Class<? extends BeliefGoalPlanBody> planBodyClass) {
+		this(planBodyClass.getSimpleName(), BeliefGoal.class, beliefName,
+				planBodyClass);
+	}
+
+	/**
+	 * Constructs a new Plan. It sets the plan library and plan body class of
+	 * this plan, and initializes the goals that it can achieve and messages it
+	 * can process. The goals are initialized with the provided goal class.
+	 * 
+	 * @param id
+	 *            plan identifier
+	 * @param goalClass
+	 *            the goal that this plan can achieve
+	 */
+	public BeliefGoalPlan(String id, String beliefName,
+			Class<? extends BeliefGoalPlanBody> planBodyClass) {
+		this(id, BeliefGoal.class, beliefName, planBodyClass);
+	}
+
+	/**
+	 * Verifies if a given goal can be achieved by this plan. When the goal is a
+	 * {@link MessageGoal}, it invokes the method
+	 * {@link AbstractPlan#canProcess(ACLMessage)}. Otherwise, it checks if the
+	 * class of this goal is contained in the goal set of this plan.
+	 * 
+	 * @param goal
+	 *            the goal to be verified.
+	 * @return true if the given goal can be achieved by this plan, false
+	 *         otherwise.
+	 */
+	public boolean canAchieve(Goal goal) {
+		boolean ok = false;
+		for (Class<? extends Goal> goalClass : getGoals()) {
+			if (goalClass.equals(goal.getClass())) {
+				if (checkBeliefGoal((BeliefGoal) goal)) {
+					ok = true;
+				}
+			}
+		}
+		return ok ? matchesContext(goal) : false;
+	}
+
+	protected boolean checkBeliefGoal(BeliefGoal beliefGoal) {
+		return beliefGoal.getBeliefName().equals(beliefName);
+	}
+
+}
diff --git a/bdi-jade/src/bdi4jade/util/plan/BeliefGoalPlanBody.java b/bdi-jade/src/bdi4jade/util/plan/BeliefGoalPlanBody.java
new file mode 100644
index 0000000..c446745
--- /dev/null
+++ b/bdi-jade/src/bdi4jade/util/plan/BeliefGoalPlanBody.java
@@ -0,0 +1,61 @@
+//----------------------------------------------------------------------------
+// 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.util.plan;
+
+import bdi4jade.plan.AbstractPlanBody;
+import bdi4jade.plan.Plan.EndState;
+import bdi4jade.util.goal.BeliefGoal;
+
+/**
+ * @author ingrid
+ * 
+ */
+public abstract class BeliefGoalPlanBody extends AbstractPlanBody {
+
+	private static final long serialVersionUID = -2512248999988800844L;
+
+	@Override
+	public final void action() {
+		if (!isGoalAchieved()) {
+			execute();
+		}
+	}
+
+	protected abstract void execute();
+
+	protected boolean isGoalAchieved() {
+		BeliefGoal goal = (BeliefGoal) getGoal();
+		if (goal.isAchieved(getBeliefBase())) {
+			setEndState(EndState.SUCCESSFUL);
+			return true;
+		}
+		return false;
+	}
+
+	@Override
+	public void onStart() {
+		if (!(getGoal() instanceof BeliefGoal))
+			throw new IllegalArgumentException("BeliefGoal expected.");
+	}
+
+}
diff --git a/bdi-jade/src/bdi4jade/util/plan/BeliefValueGoalPlan.java b/bdi-jade/src/bdi4jade/util/plan/BeliefValueGoalPlan.java
new file mode 100644
index 0000000..2f97a44
--- /dev/null
+++ b/bdi-jade/src/bdi4jade/util/plan/BeliefValueGoalPlan.java
@@ -0,0 +1,62 @@
+//----------------------------------------------------------------------------
+// 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.util.plan;
+
+import bdi4jade.util.goal.BeliefGoal;
+import bdi4jade.util.goal.BeliefValueGoal;
+
+/**
+ * @author ingrid
+ * 
+ */
+public class BeliefValueGoalPlan extends BeliefGoalPlan {
+
+	private final Class<?> beliefValueClass;
+
+	public BeliefValueGoalPlan(
+			Class<? extends BeliefValueGoal> beliefGoalClass,
+			String beliefName, Class<?> beliefValueClass,
+			Class<? extends BeliefGoalPlanBody> planBodyClass) {
+		this(planBodyClass.getSimpleName(), beliefGoalClass, beliefName,
+				beliefValueClass, planBodyClass);
+	}
+
+	public BeliefValueGoalPlan(String id,
+			Class<? extends BeliefValueGoal> beliefGoalClass,
+			String beliefName, Class<?> beliefValueClass,
+			Class<? extends BeliefGoalPlanBody> planBodyClass) {
+		super(id, beliefGoalClass, beliefName, planBodyClass);
+		this.beliefValueClass = beliefValueClass;
+	}
+
+	@Override
+	protected boolean checkBeliefGoal(BeliefGoal beliefGoal) {
+		if (super.checkBeliefGoal(beliefGoal)) {
+			return beliefValueClass
+					.isInstance(((BeliefValueGoal<?>) beliefGoal).getValue());
+		} else {
+			return false;
+		}
+	}
+
+}
diff --git a/bdi-jade-test/src/bdi4jade/examples/blocksworld/BlocksWorldCapability.java b/bdi-jade-test/src/bdi4jade/examples/blocksworld/BlocksWorldCapability.java
index 4fbf3bd..49803ac 100644
--- a/bdi-jade-test/src/bdi4jade/examples/blocksworld/BlocksWorldCapability.java
+++ b/bdi-jade-test/src/bdi4jade/examples/blocksworld/BlocksWorldCapability.java
@@ -49,6 +49,7 @@ import bdi4jade.goal.Goal;
 import bdi4jade.plan.Plan;
 import bdi4jade.plan.SimplePlan;
 import bdi4jade.util.goal.BeliefSetValueGoal;
+import bdi4jade.util.plan.BeliefValueGoalPlan;
 
 /**
  * @author ingrid
@@ -99,23 +100,12 @@ public class BlocksWorldCapability extends Capability implements GoalListener {
 	private static Set<Plan> getPlans() {
 		Set<Plan> plans = new HashSet<Plan>();
 
-		plans.add(new SimplePlan(BeliefSetValueGoal.class,
-				AchieveOnPlanBody.class) {
-			@Override
-			protected boolean matchesContext(Goal goal) {
-				return BlocksWorldCapability.BELIEF_ON
-						.equals(((BeliefSetValueGoal<?>) goal)
-								.getBeliefSetName());
-			}
-		});
-		plans.add(new SimplePlan(BeliefSetValueGoal.class, ClearPlanBody.class) {
-			@Override
-			protected boolean matchesContext(Goal goal) {
-				return BlocksWorldCapability.BELIEF_CLEAR
-						.equals(((BeliefSetValueGoal<?>) goal)
-								.getBeliefSetName());
-			}
-		});
+		plans.add(new BeliefValueGoalPlan(BeliefSetValueGoal.class,
+				BlocksWorldCapability.BELIEF_ON, On.class,
+				AchieveOnPlanBody.class));
+		plans.add(new BeliefValueGoalPlan(BeliefSetValueGoal.class,
+				BlocksWorldCapability.BELIEF_CLEAR, Clear.class,
+				ClearPlanBody.class));
 		plans.add(new SimplePlan(PerformMove.class, PerformMovePlanBody.class) {
 			@Override
 			@SuppressWarnings("unchecked")
diff --git a/bdi-jade-test/src/bdi4jade/examples/blocksworld/plan/AchieveOnPlanBody.java b/bdi-jade-test/src/bdi4jade/examples/blocksworld/plan/AchieveOnPlanBody.java
index ddbd4c6..d1c2a36 100644
--- a/bdi-jade-test/src/bdi4jade/examples/blocksworld/plan/AchieveOnPlanBody.java
+++ b/bdi-jade-test/src/bdi4jade/examples/blocksworld/plan/AchieveOnPlanBody.java
@@ -22,77 +22,86 @@
 
 package bdi4jade.examples.blocksworld.plan;
 
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
 import bdi4jade.examples.blocksworld.BlocksWorldCapability;
 import bdi4jade.examples.blocksworld.domain.Clear;
 import bdi4jade.examples.blocksworld.domain.On;
 import bdi4jade.examples.blocksworld.domain.Thing;
 import bdi4jade.examples.blocksworld.goal.PerformMove;
-import bdi4jade.plan.Plan.EndState;
-import bdi4jade.plan.AbstractPlanBody;
+import bdi4jade.goal.Goal;
 import bdi4jade.util.goal.BeliefSetValueGoal;
+import bdi4jade.util.plan.BeliefGoalPlanBody;
 
 /**
  * @author ingrid
  * 
  */
-public class AchieveOnPlanBody extends AbstractPlanBody {
+public class AchieveOnPlanBody extends BeliefGoalPlanBody {
+
+	enum Step {
+		CLEAR_1, CLEAR_2, PERFORM_MOVE, WAIT_CLEAR_1, WAIT_CLEAR_2, WAIT_DONE;
+	}
 
 	private static final long serialVersionUID = -5919677537834351951L;
 
-	private int counter;
+	private Log log;
+	private Step step;
 	private Thing thing1;
 	private Thing thing2;
 
 	public AchieveOnPlanBody() {
-		this.counter = 0;
+		this.log = LogFactory.getLog(this.getClass());
 	}
 
 	@Override
-	public void action() {
-		switch (counter) {
-		case 0:
-			if (new BeliefSetValueGoal<On>(BlocksWorldCapability.BELIEF_ON,
-					new On(thing1, thing2)).isAchieved(getBeliefBase())) {
-				counter = 6;
-			} else {
-				counter = checkClearAndDispatch(thing1) ? 1 : 2;
+	public void execute() {
+		switch (step) {
+		case CLEAR_1:
+			Goal goal = new BeliefSetValueGoal<Clear>(
+					BlocksWorldCapability.BELIEF_CLEAR, new Clear(thing1));
+			dispatchSubgoalAndListen(goal);
+			log.debug("Goal dispatched: " + goal);
+			step = Step.WAIT_CLEAR_1;
+			break;
+		case WAIT_CLEAR_1:
+			if (getGoalEvent() != null) {
+				step = Step.CLEAR_2;
 			}
 			break;
-		case 2:
-			counter = checkClearAndDispatch(thing2) ? 3 : 4;
+		case CLEAR_2:
+			goal = new BeliefSetValueGoal<Clear>(
+					BlocksWorldCapability.BELIEF_CLEAR, new Clear(thing2));
+			dispatchSubgoalAndListen(goal);
+			log.debug("Goal dispatched: " + goal);
+			step = Step.WAIT_CLEAR_2;
 			break;
-		case 4:
-			dispatchSubgoalAndListen(new PerformMove(thing1, thing2));
-			counter = 5;
-		case 1:
-		case 3:
-		case 5:
-			if (getGoalEvent() != null)
-				counter++;
+		case WAIT_CLEAR_2:
+			if (getGoalEvent() != null) {
+				step = Step.PERFORM_MOVE;
+			}
+			break;
+		case PERFORM_MOVE:
+			goal = new PerformMove(thing1, thing2);
+			dispatchSubgoalAndListen(goal);
+			log.debug("Goal dispatched: " + goal);
+			step = Step.WAIT_DONE;
+			break;
+		case WAIT_DONE:
+			getGoalEvent();
 			break;
-		}
-
-		if (counter == 6)
-			setEndState(EndState.SUCCESSFUL);
-	}
-
-	private boolean checkClearAndDispatch(Thing thing) {
-		BeliefSetValueGoal<Clear> clearBelief = new BeliefSetValueGoal<Clear>(
-				BlocksWorldCapability.BELIEF_CLEAR, new Clear(thing1));
-		if (!clearBelief.isAchieved(getBeliefBase())) {
-			dispatchSubgoalAndListen(clearBelief);
-			return true;
-		} else {
-			return false;
 		}
 	}
 
 	@Override
 	@SuppressWarnings("unchecked")
 	public void onStart() {
+		super.onStart();
 		BeliefSetValueGoal<On> achieveOn = (BeliefSetValueGoal<On>) getGoal();
 		this.thing1 = achieveOn.getValue().getThing1();
 		this.thing2 = achieveOn.getValue().getThing2();
+		this.step = Step.CLEAR_1;
 	}
 
 }
diff --git a/bdi-jade-test/src/bdi4jade/examples/blocksworld/plan/ClearPlanBody.java b/bdi-jade-test/src/bdi4jade/examples/blocksworld/plan/ClearPlanBody.java
index 333a9e1..2be9df5 100644
--- a/bdi-jade-test/src/bdi4jade/examples/blocksworld/plan/ClearPlanBody.java
+++ b/bdi-jade-test/src/bdi4jade/examples/blocksworld/plan/ClearPlanBody.java
@@ -22,64 +22,54 @@
 
 package bdi4jade.examples.blocksworld.plan;
 
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
 import bdi4jade.belief.BeliefSet;
 import bdi4jade.examples.blocksworld.BlocksWorldCapability;
 import bdi4jade.examples.blocksworld.domain.Clear;
 import bdi4jade.examples.blocksworld.domain.On;
 import bdi4jade.examples.blocksworld.domain.Thing;
-import bdi4jade.plan.Plan.EndState;
-import bdi4jade.plan.AbstractPlanBody;
+import bdi4jade.goal.Goal;
 import bdi4jade.util.goal.BeliefSetValueGoal;
+import bdi4jade.util.plan.BeliefGoalPlanBody;
 
 /**
  * @author ingrid
  * 
  */
-public class ClearPlanBody extends AbstractPlanBody {
+public class ClearPlanBody extends BeliefGoalPlanBody {
 
 	private static final long serialVersionUID = -5919677537834351951L;
 
-	private int index;
-	private On on;
+	private Log log;
 	private BeliefSet<On> onSet;
 	private Thing thing;
-	private boolean waiting;
 
 	public ClearPlanBody() {
-		this.waiting = false;
-		this.index = 0;
+		this.log = LogFactory.getLog(this.getClass());
 	}
 
 	@Override
-	public void action() {
-		if (!waiting) {
-			for (; index < Thing.THINGS.length; index++) {
-				Thing t = Thing.THINGS[index];
-				on = new On(t, thing);
-				if (onSet.hasValue(on)) {
-
-					dispatchSubgoalAndListen(new BeliefSetValueGoal<On>(
-							BlocksWorldCapability.BELIEF_ON, new On(t,
-									Thing.TABLE)));
-					waiting = true;
-					break;
-				}
+	public void execute() {
+		for (int i = 0; i < Thing.THINGS.length; i++) {
+			Thing t = Thing.THINGS[i];
+			On on = new On(t, thing);
+			if (onSet.hasValue(on)) {
+				Goal goal = new BeliefSetValueGoal<On>(
+						BlocksWorldCapability.BELIEF_ON, new On(t, Thing.TABLE));
+				dispatchSubgoalAndListen(goal);
+				log.debug("Goal dispatched: " + goal);
+				getGoalEvent();
+				break;
 			}
-		} else if (getGoalEvent() != null) {
-			onSet.removeValue(on);
-			on = null;
-			waiting = false;
-			index++;
-		}
-
-		if (index >= Thing.THINGS.length) {
-			setEndState(EndState.SUCCESSFUL);
 		}
 	}
 
 	@Override
 	@SuppressWarnings("unchecked")
 	public void onStart() {
+		super.onStart();
 		this.onSet = (BeliefSet<On>) getBeliefBase().getBelief(
 				BlocksWorldCapability.BELIEF_ON);
 		BeliefSetValueGoal<Clear> achieveClear = (BeliefSetValueGoal<Clear>) getGoal();
diff --git a/bdi-jade-test/src/bdi4jade/examples/blocksworld/plan/PerformMovePlanBody.java b/bdi-jade-test/src/bdi4jade/examples/blocksworld/plan/PerformMovePlanBody.java
index 9bc2237..ca8bb89 100644
--- a/bdi-jade-test/src/bdi4jade/examples/blocksworld/plan/PerformMovePlanBody.java
+++ b/bdi-jade-test/src/bdi4jade/examples/blocksworld/plan/PerformMovePlanBody.java
@@ -22,14 +22,17 @@
 
 package bdi4jade.examples.blocksworld.plan;
 
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
 import bdi4jade.belief.BeliefSet;
 import bdi4jade.examples.blocksworld.BlocksWorldCapability;
 import bdi4jade.examples.blocksworld.domain.Clear;
 import bdi4jade.examples.blocksworld.domain.On;
 import bdi4jade.examples.blocksworld.domain.Thing;
 import bdi4jade.examples.blocksworld.goal.PerformMove;
-import bdi4jade.plan.Plan.EndState;
 import bdi4jade.plan.AbstractPlanBody;
+import bdi4jade.plan.Plan.EndState;
 
 /**
  * @author ingrid
@@ -40,14 +43,20 @@ public class PerformMovePlanBody extends AbstractPlanBody {
 	private static final long serialVersionUID = -5919677537834351951L;
 
 	private BeliefSet<Clear> clearSet;
+	private Log log;
 	private BeliefSet<On> onSet;
 	private Thing thing1;
 	private Thing thing2;
 
+	public PerformMovePlanBody() {
+		this.log = LogFactory.getLog(this.getClass());
+	}
+
 	@Override
 	public void action() {
 		if (!thing2.equals(Thing.TABLE)) {
 			clearSet.removeValue(new Clear(thing2));
+			log.debug("~" + new Clear(thing2));
 		}
 
 		for (Thing thing : Thing.THINGS) {
@@ -56,11 +65,14 @@ public class PerformMovePlanBody extends AbstractPlanBody {
 				onSet.removeValue(on);
 				if (!Thing.TABLE.equals(thing)) {
 					clearSet.addValue(new Clear(thing));
+					log.debug(new Clear(thing));
 				}
 			}
 		}
 
 		onSet.addValue(new On(thing1, thing2));
+		log.debug(new On(thing1, thing2));
+
 		setEndState(EndState.SUCCESSFUL);
 	}
 
diff --git a/bdi-jade-test/src/bdi4jade/examples/blocksworld/plan/TopLevelPlanBody.java b/bdi-jade-test/src/bdi4jade/examples/blocksworld/plan/TopLevelPlanBody.java
index 15130f5..fec122a 100644
--- a/bdi-jade-test/src/bdi4jade/examples/blocksworld/plan/TopLevelPlanBody.java
+++ b/bdi-jade-test/src/bdi4jade/examples/blocksworld/plan/TopLevelPlanBody.java
@@ -28,8 +28,9 @@ import org.apache.commons.logging.LogFactory;
 import bdi4jade.examples.blocksworld.BlocksWorldCapability;
 import bdi4jade.examples.blocksworld.domain.On;
 import bdi4jade.examples.blocksworld.goal.AchieveBlocksStacked;
-import bdi4jade.plan.Plan.EndState;
+import bdi4jade.goal.Goal;
 import bdi4jade.plan.AbstractPlanBody;
+import bdi4jade.plan.Plan.EndState;
 import bdi4jade.util.goal.BeliefSetValueGoal;
 
 /**
@@ -51,14 +52,18 @@ public class TopLevelPlanBody extends AbstractPlanBody {
 
 	@Override
 	public void action() {
+		// If a subgoal has been dispatched, wait for its completion
 		if (counter != 0) {
 			if ((getGoalEvent() == null)) {
 				return;
 			}
 		}
+		// Dispatch the next subgoal, if there are subgoals left
 		if (counter != target.length) {
-			dispatchSubgoalAndListen(new BeliefSetValueGoal<On>(
-					BlocksWorldCapability.BELIEF_ON, target[counter]));
+			Goal goal = new BeliefSetValueGoal<On>(
+					BlocksWorldCapability.BELIEF_ON, target[counter]);
+			dispatchSubgoalAndListen(goal);
+			log.debug("Goal dispatched: " + goal);
 		}
 		counter++;
 
@@ -76,8 +81,7 @@ public class TopLevelPlanBody extends AbstractPlanBody {
 	@Override
 	public void onStart() {
 		log.info("World Model at start is:");
-		this.target = ((AchieveBlocksStacked) getGoal())
-				.getTarget();
+		this.target = ((AchieveBlocksStacked) getGoal()).getTarget();
 		log.info(getBeliefBase());
 	}