bdi4jade

Changes

Details

diff --git a/bdi-jade/src/bdi4jade/belief/PredicateBelief.java b/bdi-jade/src/bdi4jade/belief/PredicateBelief.java
index 687dc02..507bb01 100644
--- a/bdi-jade/src/bdi4jade/belief/PredicateBelief.java
+++ b/bdi-jade/src/bdi4jade/belief/PredicateBelief.java
@@ -22,7 +22,7 @@
 
 package bdi4jade.belief;
 
-import bdi4jade.goal.Goal;
+import bdi4jade.goal.PredicateGoal;
 
 /**
  * This interface represents a belief that is a logic predicate. The information
@@ -37,6 +37,6 @@ import bdi4jade.goal.Goal;
  */
 public interface PredicateBelief<K> extends Belief<K, Boolean> {
 
-	void setValue(Boolean value, Goal goal);
+	void setValue(Boolean value, PredicateGoal<?> goal);
 	
 }
diff --git a/bdi-jade/src/bdi4jade/belief/TransientPredicate.java b/bdi-jade/src/bdi4jade/belief/TransientPredicate.java
index 8b110b6..170350b 100644
--- a/bdi-jade/src/bdi4jade/belief/TransientPredicate.java
+++ b/bdi-jade/src/bdi4jade/belief/TransientPredicate.java
@@ -24,7 +24,7 @@ package bdi4jade.belief;
 
 import bdi4jade.event.BeliefEvent;
 import bdi4jade.event.BeliefEvent.Action;
-import bdi4jade.goal.Goal;
+import bdi4jade.goal.PredicateGoal;
 
 /**
  * This class extends the {@link TransientBelief} class and represents a
@@ -83,8 +83,8 @@ public class TransientPredicate<K> extends TransientBelief<K, Boolean> implement
 	 * @see bdi4jade.belief.PredicateBelief#setValue(java.lang.Boolean, bdi4jade.goal.Goal)
 	 */
 	@Override
-	public void setValue(Boolean value, Goal goal) {
-		updateValue(value);
+	public void setValue(Boolean value, PredicateGoal<?> goal) {
+		super.setValue(value);
 		notifyBeliefBases(new BeliefEvent(this, Action.BELIEF_UPDATED, goal));
 	}
 
diff --git a/bdi-jade-extensions/src/bdi4jade/extension/remediation/reasoning/RemediationOptionGenerationFunction.java b/bdi-jade-extensions/src/bdi4jade/extension/remediation/reasoning/RemediationOptionGenerationFunction.java
index a530329..44adc8e 100644
--- a/bdi-jade-extensions/src/bdi4jade/extension/remediation/reasoning/RemediationOptionGenerationFunction.java
+++ b/bdi-jade-extensions/src/bdi4jade/extension/remediation/reasoning/RemediationOptionGenerationFunction.java
@@ -109,7 +109,6 @@ public class RemediationOptionGenerationFunction extends RevertingOptionGenerati
 
 			// Algorithm 1 - lines 18-35
 			if (cep.getEffectGoalStatus() != null) {
-				System.out.println("Effect Status not null: " + cep.getEffectGoalStatus());
 				if (knownCause(cep, cep.getCauseEffectRelationship())) {
 
 					// Reversion trigger is updated with current cause factor predicates
@@ -262,22 +261,16 @@ public class RemediationOptionGenerationFunction extends RevertingOptionGenerati
 	}
 
 	private void updateReversionTrigger(CauseEffectProblem cep) {
-		ArrayList<Predicate> reversionTrigger = new ArrayList<>();
+		HashMap<Predicate, Boolean> reversionTrigger = new HashMap<>();
 		for (CauseFactorStatus causeFactor : cep.getCauseFactorStatus()) {
-			reversionTrigger.add(causeFactor.getFact().getPredicate());
+			reversionTrigger.put(causeFactor.getFact().getPredicate(), !causeFactor.getFact().getValue());
 		}
 
 		Map<Goal, GoalAchievementMetadata> gams = ((RemediationCapability) this.capability)
 				.getGoalAchievementMetadata();
 		GoalAchievementMetadata gam = gams.get(cep.getEffectGoal());
 
-		// TODO Remove Sysouts
-		if (gam != null) {
-			gam.setReversionTrigger(reversionTrigger);
-		} else {
-			System.out.println("GAM Nulo!");
-		}
-
+		gam.setReversionTrigger(reversionTrigger);
 	}
 
 }
diff --git a/bdi-jade-extensions/src/bdi4jade/extension/undo/GoalAchievementMetadata.java b/bdi-jade-extensions/src/bdi4jade/extension/undo/GoalAchievementMetadata.java
index 04cda3b..164b96a 100644
--- a/bdi-jade-extensions/src/bdi4jade/extension/undo/GoalAchievementMetadata.java
+++ b/bdi-jade-extensions/src/bdi4jade/extension/undo/GoalAchievementMetadata.java
@@ -45,7 +45,7 @@ import javafx.util.Pair;
 public class GoalAchievementMetadata {
 
 	private final static Integer MAX_EXECUTED_PLANS = 500;
-	private final static Integer MAX_TIME = 100000;
+	private final static Integer MAX_TIME = Integer.MAX_VALUE;
 	private Map<Predicate, List<Pair<Boolean, Long>>> beliefChangeTrace;
 	private Long createdTime;
 	private PredicateGoal<?> goal;
@@ -53,7 +53,7 @@ public class GoalAchievementMetadata {
 	private Integer maxExecutedPlans;
 	private Integer maxTime;
 	private Integer planCounter;
-	private List<Predicate> reversionTrigger;
+	private Map<Predicate, Boolean> reversionTrigger;
 	private Boolean rollback;
 
 	/**
@@ -98,8 +98,8 @@ public class GoalAchievementMetadata {
 	 *            a flag that indicates the desire of a rollback in case of a plan
 	 *            failure.
 	 * @param reversionTrigger
-	 *            a list of {@link Predicate} that specifies the condition in which
-	 *            a reversion will be activated.
+	 *            a map of {@link Predicate} and boolean values that specifies the
+	 *            condition in which a reversion will be activated.
 	 * @param maxExecutedPlans
 	 *            the number of plans that can be executed after achieving the
 	 *            related goal before this goal achievement metadata is discarded.
@@ -108,8 +108,8 @@ public class GoalAchievementMetadata {
 	 *            this goal achievement metadata is discarded.
 	 */
 	public GoalAchievementMetadata(PredicateGoal<?> goal, Intention intention, Boolean rollback,
-			List<Predicate> reversionTrigger, Integer maxExecutedPlans, Integer maxTime) {
-		// TODO Created time must be refactored to achieved time.
+			Map<Predicate, Boolean> reversionTrigger, Integer maxExecutedPlans, Integer maxTime) {
+		// TODO Refactor: Created time must be refactored to achieved time.
 		this.createdTime = System.currentTimeMillis();
 		this.beliefChangeTrace = new HashMap<>();
 		this.goal = goal;
@@ -117,7 +117,7 @@ public class GoalAchievementMetadata {
 		this.maxExecutedPlans = maxExecutedPlans;
 		this.maxTime = maxTime;
 		this.planCounter = 0;
-		this.reversionTrigger = new ArrayList<>();
+		this.reversionTrigger = new HashMap<>();
 		this.rollback = rollback;
 
 		if (reversionTrigger != null) {
@@ -225,7 +225,7 @@ public class GoalAchievementMetadata {
 	 * 
 	 * @return the reversionTrigger.
 	 */
-	public List<Predicate> getReversionTrigger() {
+	public Map<Predicate, Boolean> getReversionTrigger() {
 		return reversionTrigger;
 	}
 
@@ -293,10 +293,14 @@ public class GoalAchievementMetadata {
 	public Boolean isReversionTriggered(BeliefBase beliefBase) {
 		Boolean triggered = true;
 
-		for (Predicate predicate : this.reversionTrigger) {
-			Boolean value = predicate.getValue(beliefBase);
-			if (value == null || value == false) {
-				triggered = false;
+		if (!this.intention.getStatus().equals(GoalStatus.ACHIEVED) || this.reversionTrigger.isEmpty()) {
+			triggered = false;
+		} else {
+			for (Predicate predicate : this.reversionTrigger.keySet()) {
+				Boolean value = predicate.getValue(beliefBase);
+				if (value == null || value != this.reversionTrigger.get(predicate)) {
+					triggered = false;
+				}
 			}
 		}
 
@@ -331,7 +335,7 @@ public class GoalAchievementMetadata {
 	 * @param reversionTrigger
 	 *            the reversionTrigger to be set.
 	 */
-	public void setReversionTrigger(List<Predicate> reversionTrigger) {
+	public void setReversionTrigger(HashMap<Predicate, Boolean> reversionTrigger) {
 		this.reversionTrigger = reversionTrigger;
 	}
 
@@ -352,12 +356,15 @@ public class GoalAchievementMetadata {
 		LinkedList<Pair<Boolean, Long>> trace = (LinkedList<Pair<Boolean, Long>>) this.beliefChangeTrace.get(predicate);
 		trace.add(new Pair<Boolean, Long>(value, System.currentTimeMillis()));
 	}
-	
+
 	@Override
 	public String toString() {
 		StringBuffer sb = new StringBuffer();
 		sb.append("< ").append(goal);
 		sb.append(", maxExecutedPlans = ").append(maxExecutedPlans);
+		sb.append(", maxTime = ").append(maxTime);
+		sb.append(", \n reversionTrigger = ").append(reversionTrigger);
+		sb.append(", \n beliefChangeTrace = ").append(beliefChangeTrace);
 		sb.append(", rollback = ").append(rollback).append(" >");
 		return sb.toString();
 	}
diff --git a/bdi-jade-extensions/src/bdi4jade/extension/undo/reasoning/RevertingOptionGenerationFunction.java b/bdi-jade-extensions/src/bdi4jade/extension/undo/reasoning/RevertingOptionGenerationFunction.java
index 91c32cc..d96427b 100644
--- a/bdi-jade-extensions/src/bdi4jade/extension/undo/reasoning/RevertingOptionGenerationFunction.java
+++ b/bdi-jade-extensions/src/bdi4jade/extension/undo/reasoning/RevertingOptionGenerationFunction.java
@@ -69,6 +69,8 @@ public class RevertingOptionGenerationFunction extends AbstractReasoningStrategy
 			for (GoalAchievementMetadata gam : gams.values()) {
 				if (gam.isReversionDeactivated()) {
 					gams.remove(gam.getGoal());
+					Map<Goal, Goal> parentGoals = ((RevertingCapability) this.capability).getParentGoals();
+					parentGoals.remove(gam.getGoal());
 				} else {
 					if (gam.isReversionActivated(this.capability.getBeliefBase())) {
 						ArrayList<Predicate> filteredChanges = gam.filterBeliefChanges(this.capability.getBeliefBase());
@@ -80,13 +82,7 @@ public class RevertingOptionGenerationFunction extends AbstractReasoningStrategy
 							goalUpdateSet.generateGoal(predicateGoal, capability);
 						}
 
-						for (Predicate predicate : filteredChanges) {
-							gam.getBeliefChangeTrace().remove(predicate);
-						}
-
-						if (!gam.isRollbackTriggered()) {
-							gams.remove(gam.getGoal());
-						}
+						gam.getBeliefChangeTrace().clear();
 					}
 				}
 			}
diff --git a/bdi-jade-extensions/src/bdi4jade/extension/undo/RevertingBDIAgent.java b/bdi-jade-extensions/src/bdi4jade/extension/undo/RevertingBDIAgent.java
index 14d216c..63c20b8 100644
--- a/bdi-jade-extensions/src/bdi4jade/extension/undo/RevertingBDIAgent.java
+++ b/bdi-jade-extensions/src/bdi4jade/extension/undo/RevertingBDIAgent.java
@@ -22,7 +22,7 @@
 
 package bdi4jade.extension.undo;
 
-import java.util.List;
+import java.util.Map;
 import java.util.stream.Collectors;
 
 import bdi4jade.core.AbstractBDIAgent;
@@ -70,7 +70,7 @@ public class RevertingBDIAgent extends AbstractBDIAgent {
 	 * @return true if the goal was added, false otherwise.
 	 */
 	public final boolean addGoal(Capability dispatcher, Goal goal, GoalListener goalListener,
-			List<Predicate> reversionTrigger, Boolean rollback, Integer maxExecutedPlans, Integer maxTime) {
+			Map<Predicate, Boolean> reversionTrigger, Boolean rollback, Integer maxExecutedPlans, Integer maxTime) {
 
 		if (super.addGoal(dispatcher, goal, goalListener)) {
 			if (goal instanceof PredicateGoal<?>) {
diff --git a/bdi-jade-extensions/src/bdi4jade/extension/undo/RevertingCapability.java b/bdi-jade-extensions/src/bdi4jade/extension/undo/RevertingCapability.java
index 235b773..9b87dfe 100644
--- a/bdi-jade-extensions/src/bdi4jade/extension/undo/RevertingCapability.java
+++ b/bdi-jade-extensions/src/bdi4jade/extension/undo/RevertingCapability.java
@@ -23,10 +23,8 @@
 package bdi4jade.extension.undo;
 
 import java.util.HashMap;
-import java.util.List;
 import java.util.Map;
 
-import bdi4jade.annotation.Belief;
 import bdi4jade.belief.PredicateBelief;
 import bdi4jade.core.BDIAgent;
 import bdi4jade.core.Capability;
@@ -36,7 +34,6 @@ import bdi4jade.event.BeliefEvent.Action;
 import bdi4jade.event.BeliefListener;
 import bdi4jade.event.GoalEvent;
 import bdi4jade.event.GoalListener;
-import bdi4jade.extension.remediation.graph.CauseEffectKnowledgeModel;
 import bdi4jade.extension.remediation.logics.Predicate;
 import bdi4jade.extension.undo.reasoning.RevertingOptionGenerationFunction;
 import bdi4jade.goal.Goal;
@@ -57,8 +54,8 @@ import bdi4jade.goal.PredicateGoal;
 public class RevertingCapability extends Capability implements BeliefListener, GoalListener {
 
 	private static final long serialVersionUID = -5556551069331273755L;
-	protected Map<Goal, GoalAchievementMetadata> gams;
-	
+	private final Map<Goal, GoalAchievementMetadata> gams;
+
 	protected Map<Goal, Goal> parentGoals;
 
 	/**
@@ -162,7 +159,7 @@ public class RevertingCapability extends Capability implements BeliefListener, G
 	 * @return the created goal achievement metadata.
 	 */
 	public GoalAchievementMetadata createGoalAchievementMetadata(PredicateGoal<?> goal, Intention intention,
-			Boolean rollback, List<Predicate> reversionTrigger, Integer maxExecutedPlans, Integer maxTime) {
+			Boolean rollback, Map<Predicate, Boolean> reversionTrigger, Integer maxExecutedPlans, Integer maxTime) {
 		GoalAchievementMetadata gam = new GoalAchievementMetadata((PredicateGoal<?>) goal, intention, rollback,
 				reversionTrigger, maxExecutedPlans, maxTime);
 		addGoalAchievementMetadata(goal, gam);
@@ -198,7 +195,7 @@ public class RevertingCapability extends Capability implements BeliefListener, G
 	 * @return the goal achievement metadata map.
 	 */
 	public Map<Goal, GoalAchievementMetadata> getGoalAchievementMetadata() {
-		return gams;
+		return this.gams;
 	}
 
 	/**
@@ -222,7 +219,7 @@ public class RevertingCapability extends Capability implements BeliefListener, G
 		while (this.parentGoals.containsKey(aux)) {
 			aux = this.parentGoals.get(aux);
 			if (this.gams.containsKey(aux)) {
-				parent = this.parentGoals.get(aux);
+				parent = aux;
 			}
 		}
 
@@ -245,10 +242,12 @@ public class RevertingCapability extends Capability implements BeliefListener, G
 	 */
 	@Override
 	public void goalPerformed(GoalEvent event) {
-		for (GoalAchievementMetadata gam : gams.values()) {
-			if (gam.getIntention().getStatus().equals(GoalStatus.ACHIEVED) && !event.getGoal().equals(gam.getGoal())
-					&& event.getStatus().equals(GoalStatus.ACHIEVED)) {
-				gam.incrementPlanCounter();
+		if (!event.isGoalAdded()) {
+			for (GoalAchievementMetadata gam : this.gams.values()) {
+				if (gam.getIntention().getStatus().equals(GoalStatus.ACHIEVED) && !event.getGoal().equals(gam.getGoal())
+						&& event.getStatus().equals(GoalStatus.ACHIEVED)) {
+					gam.incrementPlanCounter();
+				}
 			}
 		}
 	}
diff --git a/bdi-jade-test/src/bdi4jade/examples/undo/ManagementCapability.java b/bdi-jade-test/src/bdi4jade/examples/undo/ManagementCapability.java
index 26262f0..8978a77 100644
--- a/bdi-jade-test/src/bdi4jade/examples/undo/ManagementCapability.java
+++ b/bdi-jade-test/src/bdi4jade/examples/undo/ManagementCapability.java
@@ -16,6 +16,7 @@ import bdi4jade.examples.undo.domain.predicate.Open;
 import bdi4jade.examples.undo.domain.predicate.TakeOff;
 import bdi4jade.examples.undo.plan.EvacuateAndVentilatePlanBody;
 import bdi4jade.examples.undo.plan.NotifyAbnormalCOPlanBody;
+import bdi4jade.examples.undo.plan.StopLeakingPlanBody;
 import bdi4jade.examples.undo.plan.request.RequestDeviceClosePlanBody;
 import bdi4jade.examples.undo.plan.request.RequestDeviceLockPlanBody;
 import bdi4jade.examples.undo.plan.request.RequestDeviceOffPlanBody;
@@ -89,6 +90,8 @@ public class ManagementCapability extends RemediationCapability {
 	private Plan requestDeviceOpenPlan;
 	@bdi4jade.annotation.Plan
 	private Plan requestDeviceClosePlan;
+	@bdi4jade.annotation.Plan
+	private Plan stopLeakingPlan;
 
 	public ManagementCapability(BDIAgent agent, String alarmAgent, String detectorAgent, String doorsAgent,
 			String fansAgent, String lightsAgent, String valveAgent, String windowsAgent) {
@@ -120,7 +123,7 @@ public class ManagementCapability extends RemediationCapability {
 		beliefs.add(leakingWaterHeater);
 		this.lightsOn = new TransientPredicate<>(new On(House.LIGHTS), false);
 		beliefs.add(lightsOn);
-		this.valveOpen = new TransientPredicate<Open>(new Open(House.VALVE), false);
+		this.valveOpen = new TransientPredicate<Open>(new Open(House.VALVE), true);
 		beliefs.add(valveOpen);
 		this.windowsOpen = new TransientPredicate<Open>(new Open(House.WINDOWS), false);
 		beliefs.add(windowsOpen);
@@ -160,6 +163,9 @@ public class ManagementCapability extends RemediationCapability {
 		this.requestDeviceClosePlan = new DefaultPlan(GoalTemplateFactory.hasBeliefOfTypeWithValue(Open.class, false),
 				RequestDeviceClosePlanBody.class);
 
+		this.stopLeakingPlan = new DefaultPlan(GoalTemplateFactory.hasBeliefOfTypeWithValue(Leak.class, false),
+				StopLeakingPlanBody.class);
+
 		this.evacuateAndVentilatePlan = new DefaultPlan(
 				GoalTemplateFactory.hasBeliefOfTypeWithValue(Abnormal.class, false),
 				EvacuateAndVentilatePlanBody.class);
@@ -169,11 +175,16 @@ public class ManagementCapability extends RemediationCapability {
 
 		private MessageTemplate mt;
 
+		@SuppressWarnings("unchecked")
 		@Override
 		public void reviewBeliefs() {
 			super.reviewBeliefs();
 			this.mt = MessageTemplate.MatchSender(new AID(detectorAgent, false));
 			ACLMessage notificationMsg = getMyAgent().receive(mt);
+			TransientPredicate<Abnormal> abnormalCO = (TransientPredicate<Abnormal>) this.capability.getBeliefBase()
+					.getBelief(new Abnormal(CO.getInstance()));
+			TransientPredicate<Leak> leakingWaterHeater = (TransientPredicate<Leak>) this.capability.getBeliefBase()
+					.getBelief(new Leak(House.WATER_HEATER));
 			if (notificationMsg != null) {
 				if (notificationMsg.getContent().equals(NotifyAbnormalCOPlanBody.ABNORMAL_CO)) {
 					abnormalCO.setValue(true);
@@ -184,6 +195,12 @@ public class ManagementCapability extends RemediationCapability {
 					abnormalCO.setValue(false);
 				}
 			}
+			
+			TransientPredicate<Open> openValve = (TransientPredicate<Open>) this.capability.getBeliefBase()
+					.getBelief(new Open(House.VALVE));
+			if (!openValve.getValue()) {
+				leakingWaterHeater.setValue(false);;
+			}
 		}
 
 	}
diff --git a/bdi-jade-test/src/bdi4jade/examples/undo/plan/AnswerRequestPlanBody.java b/bdi-jade-test/src/bdi4jade/examples/undo/plan/AnswerRequestPlanBody.java
index 8c44a15..722772a 100644
--- a/bdi-jade-test/src/bdi4jade/examples/undo/plan/AnswerRequestPlanBody.java
+++ b/bdi-jade-test/src/bdi4jade/examples/undo/plan/AnswerRequestPlanBody.java
@@ -42,7 +42,7 @@ public class AnswerRequestPlanBody extends AbstractPlanBody {
 			act(requestMsg);
 
 			this.myAgent.send(reply);
-			log.info("Reply sent to agent " + requestMsg.getSender().getName() + "!");
+			log.info(this.myAgent.getName() + ": Reply sent to agent " + requestMsg.getSender().getName() + "!");
 			setEndState(EndState.SUCCESSFUL);
 		} catch (InterruptedException e) {
 			e.printStackTrace();
diff --git a/bdi-jade-test/src/bdi4jade/examples/undo/plan/request/RequestDeviceClosePlanBody.java b/bdi-jade-test/src/bdi4jade/examples/undo/plan/request/RequestDeviceClosePlanBody.java
index 35a4ea3..938d092 100644
--- a/bdi-jade-test/src/bdi4jade/examples/undo/plan/request/RequestDeviceClosePlanBody.java
+++ b/bdi-jade-test/src/bdi4jade/examples/undo/plan/request/RequestDeviceClosePlanBody.java
@@ -76,7 +76,7 @@ public class RequestDeviceClosePlanBody extends RevertingPlanBody {
 		ACLMessage reply = myAgent.receive(mt);
 		if (reply != null) {
 			if (reply.getContent().equals(AnswerRequestPlanBody.SUCCEEDED)) {
-				belief.setValue(false, this.getGoal());
+				belief.setValue(false, (PredicateGoal<Open>) this.getGoal());
 				log.info(reply.getSender().getName() + ": " + reply.getContent());
 				setEndState(EndState.SUCCESSFUL);
 			} else {
diff --git a/bdi-jade-test/src/bdi4jade/examples/undo/plan/request/RequestDeviceLockPlanBody.java b/bdi-jade-test/src/bdi4jade/examples/undo/plan/request/RequestDeviceLockPlanBody.java
index 4b9fcf7..1d26c00 100644
--- a/bdi-jade-test/src/bdi4jade/examples/undo/plan/request/RequestDeviceLockPlanBody.java
+++ b/bdi-jade-test/src/bdi4jade/examples/undo/plan/request/RequestDeviceLockPlanBody.java
@@ -31,6 +31,7 @@ import bdi4jade.examples.undo.domain.House;
 import bdi4jade.examples.undo.domain.predicate.Locked;
 import bdi4jade.examples.undo.plan.AnswerRequestPlanBody;
 import bdi4jade.extension.undo.RevertingPlanBody;
+import bdi4jade.goal.PredicateGoal;
 import bdi4jade.plan.Plan.EndState;
 import jade.core.AID;
 import jade.lang.acl.ACLMessage;
@@ -72,7 +73,7 @@ public class RequestDeviceLockPlanBody extends RevertingPlanBody {
 				if (reply.getContent().equals(AnswerRequestPlanBody.SUCCEEDED)) {
 					TransientPredicate<Locked> doorsUnlock = (TransientPredicate<Locked>) this.getCapability()
 							.getBeliefBase().getBelief(new Locked(House.DOORS));
-					doorsUnlock.setValue(true, this.getGoal());
+					doorsUnlock.setValue(true, (PredicateGoal<Locked>) this.getGoal());
 					log.info(reply.getSender().getName() + ": " + reply.getContent());
 					setEndState(EndState.SUCCESSFUL);
 				} else {
diff --git a/bdi-jade-test/src/bdi4jade/examples/undo/plan/request/RequestDeviceOffPlanBody.java b/bdi-jade-test/src/bdi4jade/examples/undo/plan/request/RequestDeviceOffPlanBody.java
index 47a1053..d401a76 100644
--- a/bdi-jade-test/src/bdi4jade/examples/undo/plan/request/RequestDeviceOffPlanBody.java
+++ b/bdi-jade-test/src/bdi4jade/examples/undo/plan/request/RequestDeviceOffPlanBody.java
@@ -71,7 +71,7 @@ public class RequestDeviceOffPlanBody extends RevertingPlanBody {
 		ACLMessage reply = myAgent.receive(mt);
 		if (reply != null) {
 			if (reply.getContent().equals(AnswerRequestPlanBody.SUCCEEDED)) {
-				belief.setValue(false, this.getGoal());
+				belief.setValue(false, (PredicateGoal<On>) this.getGoal());
 				log.info(reply.getSender().getName() + ": " + reply.getContent());
 				setEndState(EndState.SUCCESSFUL);
 			} else {
diff --git a/bdi-jade-test/src/bdi4jade/examples/undo/plan/request/RequestDeviceOnPlanBody.java b/bdi-jade-test/src/bdi4jade/examples/undo/plan/request/RequestDeviceOnPlanBody.java
index 5e9590a..5ad972d 100644
--- a/bdi-jade-test/src/bdi4jade/examples/undo/plan/request/RequestDeviceOnPlanBody.java
+++ b/bdi-jade-test/src/bdi4jade/examples/undo/plan/request/RequestDeviceOnPlanBody.java
@@ -71,7 +71,7 @@ public class RequestDeviceOnPlanBody extends RevertingPlanBody {
 		ACLMessage reply = myAgent.receive(mt);
 		if (reply != null) {
 			if (reply.getContent().equals(AnswerRequestPlanBody.SUCCEEDED)) {
-				belief.setValue(true, this.getGoal());
+				belief.setValue(true, (PredicateGoal<On>) this.getGoal());
 				log.info(reply.getSender().getName() + ": " + reply.getContent());
 				setEndState(EndState.SUCCESSFUL);
 			} else {
diff --git a/bdi-jade-test/src/bdi4jade/examples/undo/plan/request/RequestDeviceOpenPlanBody.java b/bdi-jade-test/src/bdi4jade/examples/undo/plan/request/RequestDeviceOpenPlanBody.java
index ffcaf9b..8198451 100644
--- a/bdi-jade-test/src/bdi4jade/examples/undo/plan/request/RequestDeviceOpenPlanBody.java
+++ b/bdi-jade-test/src/bdi4jade/examples/undo/plan/request/RequestDeviceOpenPlanBody.java
@@ -76,7 +76,7 @@ public class RequestDeviceOpenPlanBody extends RevertingPlanBody {
 		ACLMessage reply = myAgent.receive(mt);
 		if (reply != null) {
 			if (reply.getContent().equals(AnswerRequestPlanBody.SUCCEEDED)) {
-				belief.setValue(true, this.getGoal());
+				belief.setValue(true, (PredicateGoal<Open>) this.getGoal());
 				log.info(reply.getSender().getName() + ": " + reply.getContent());
 				setEndState(EndState.SUCCESSFUL);
 			} else {
diff --git a/bdi-jade-test/src/bdi4jade/examples/undo/plan/request/RequestDeviceShutdownPlanBody.java b/bdi-jade-test/src/bdi4jade/examples/undo/plan/request/RequestDeviceShutdownPlanBody.java
index d4567da..62ab306 100644
--- a/bdi-jade-test/src/bdi4jade/examples/undo/plan/request/RequestDeviceShutdownPlanBody.java
+++ b/bdi-jade-test/src/bdi4jade/examples/undo/plan/request/RequestDeviceShutdownPlanBody.java
@@ -31,6 +31,7 @@ import bdi4jade.examples.undo.domain.House;
 import bdi4jade.examples.undo.domain.predicate.TakeOff;
 import bdi4jade.examples.undo.plan.AnswerRequestPlanBody;
 import bdi4jade.extension.undo.RevertingPlanBody;
+import bdi4jade.goal.PredicateGoal;
 import bdi4jade.plan.Plan.EndState;
 import jade.core.AID;
 import jade.lang.acl.ACLMessage;
@@ -72,7 +73,7 @@ public class RequestDeviceShutdownPlanBody extends RevertingPlanBody {
 				if (reply.getContent().equals(AnswerRequestPlanBody.SUCCEEDED)) {
 					TransientPredicate<TakeOff> alarmTakeOff = (TransientPredicate<TakeOff>) this.getCapability()
 							.getBeliefBase().getBelief(new TakeOff(House.ALARM));
-					alarmTakeOff.setValue(false, this.getGoal());
+					alarmTakeOff.setValue(false, (PredicateGoal<TakeOff>) this.getGoal());
 					log.info(reply.getSender().getName() + ": " + reply.getContent());
 					setEndState(EndState.SUCCESSFUL);
 				} else {
diff --git a/bdi-jade-test/src/bdi4jade/examples/undo/plan/request/RequestDeviceTakeOffPlanBody.java b/bdi-jade-test/src/bdi4jade/examples/undo/plan/request/RequestDeviceTakeOffPlanBody.java
index 47cadfa..7cbbb92 100644
--- a/bdi-jade-test/src/bdi4jade/examples/undo/plan/request/RequestDeviceTakeOffPlanBody.java
+++ b/bdi-jade-test/src/bdi4jade/examples/undo/plan/request/RequestDeviceTakeOffPlanBody.java
@@ -10,6 +10,7 @@ import bdi4jade.examples.undo.domain.House;
 import bdi4jade.examples.undo.domain.predicate.TakeOff;
 import bdi4jade.examples.undo.plan.AnswerRequestPlanBody;
 import bdi4jade.extension.undo.RevertingPlanBody;
+import bdi4jade.goal.PredicateGoal;
 import bdi4jade.plan.Plan.EndState;
 import jade.core.AID;
 import jade.lang.acl.ACLMessage;
@@ -53,7 +54,7 @@ public class RequestDeviceTakeOffPlanBody extends RevertingPlanBody {
 				if (reply.getContent().equals(AnswerRequestPlanBody.SUCCEEDED)) {
 					TransientPredicate<TakeOff> alarmTakeOff = (TransientPredicate<TakeOff>) this.getCapability()
 							.getBeliefBase().getBelief(new TakeOff(House.ALARM));
-					alarmTakeOff.setValue(true, this.getGoal());
+					alarmTakeOff.setValue(true, (PredicateGoal<TakeOff>) this.getGoal());
 					log.info(reply.getSender().getName() + ": " + reply.getContent());
 					setEndState(EndState.SUCCESSFUL);
 				} else {
diff --git a/bdi-jade-test/src/bdi4jade/examples/undo/plan/request/RequestDeviceUnlockPlanBody.java b/bdi-jade-test/src/bdi4jade/examples/undo/plan/request/RequestDeviceUnlockPlanBody.java
index b63e708..cedc6de 100644
--- a/bdi-jade-test/src/bdi4jade/examples/undo/plan/request/RequestDeviceUnlockPlanBody.java
+++ b/bdi-jade-test/src/bdi4jade/examples/undo/plan/request/RequestDeviceUnlockPlanBody.java
@@ -9,6 +9,7 @@ import bdi4jade.examples.undo.domain.House;
 import bdi4jade.examples.undo.domain.predicate.Locked;
 import bdi4jade.examples.undo.plan.AnswerRequestPlanBody;
 import bdi4jade.extension.undo.RevertingPlanBody;
+import bdi4jade.goal.PredicateGoal;
 import bdi4jade.plan.Plan.EndState;
 import jade.core.AID;
 import jade.lang.acl.ACLMessage;
@@ -50,7 +51,7 @@ public class RequestDeviceUnlockPlanBody extends RevertingPlanBody {
 				if (reply.getContent().equals(AnswerRequestPlanBody.SUCCEEDED)) {
 					TransientPredicate<Locked> doorsUnlock = (TransientPredicate<Locked>) this.getCapability()
 							.getBeliefBase().getBelief(new Locked(House.DOORS));
-					doorsUnlock.setValue(false, this.getGoal());
+					doorsUnlock.setValue(false, (PredicateGoal<Locked>) this.getGoal());
 					log.info(reply.getSender().getName() + ": " + reply.getContent());
 					setEndState(EndState.SUCCESSFUL);
 				} else {
diff --git a/bdi-jade-test/src/bdi4jade/examples/undo/plan/StopLeakingPlanBody.java b/bdi-jade-test/src/bdi4jade/examples/undo/plan/StopLeakingPlanBody.java
new file mode 100644
index 0000000..22abc84
--- /dev/null
+++ b/bdi-jade-test/src/bdi4jade/examples/undo/plan/StopLeakingPlanBody.java
@@ -0,0 +1,22 @@
+package bdi4jade.examples.undo.plan;
+
+import bdi4jade.examples.undo.domain.House;
+import bdi4jade.examples.undo.domain.predicate.Open;
+import bdi4jade.goal.PredicateGoal;
+import bdi4jade.plan.planbody.BeliefGoalPlanBody;
+
+/**
+ * @author jgfaccin
+ *
+ */
+public class StopLeakingPlanBody extends BeliefGoalPlanBody {
+
+	private static final long serialVersionUID = -7541320551634856808L;
+
+	@Override
+	protected void execute() {
+		dispatchSubgoal(new PredicateGoal<Open>(new Open(House.VALVE), false));
+		block();
+	}
+	
+}