bdi4jade

Running example.

3/5/2018 9:39:08 AM

Details

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 d02928d..dc8cc7f 100644
--- a/bdi-jade-extensions/src/bdi4jade/extension/remediation/reasoning/RemediationOptionGenerationFunction.java
+++ b/bdi-jade-extensions/src/bdi4jade/extension/remediation/reasoning/RemediationOptionGenerationFunction.java
@@ -32,7 +32,6 @@ import bdi4jade.goal.PredicateGoal;
 
 public class RemediationOptionGenerationFunction extends RevertingOptionGenerationFunction {
 
-	private Capability capability;
 	private final Map<Goal, CauseEffectProblem> causeEffectProblems;
 
 	public RemediationOptionGenerationFunction(Capability capability) {
@@ -203,17 +202,6 @@ public class RemediationOptionGenerationFunction extends RevertingOptionGenerati
 		return Boolean.TRUE;
 	}
 
-	@Override
-	public void setCapability(Capability capability) {
-		if (this.capability != null) {
-			if (!this.capability.equals(capability)) {
-				throw new IllegalArgumentException(
-						"This reasoning strategy is already associated with another capability.");
-			}
-		}
-		this.capability = capability;
-	}
-
 	private void setEndState(CauseEffectProblem cep) {
 		Collection<CauseFactorStatus> causeEffectStatus = cep.getCauseFactorStatus();
 		GoalStatus effectStatus = cep.getEffectGoalStatus();
diff --git a/bdi-jade-extensions/src/bdi4jade/extension/remediation/RemediationCapability.java b/bdi-jade-extensions/src/bdi4jade/extension/remediation/RemediationCapability.java
index d95f41b..caab367 100644
--- a/bdi-jade-extensions/src/bdi4jade/extension/remediation/RemediationCapability.java
+++ b/bdi-jade-extensions/src/bdi4jade/extension/remediation/RemediationCapability.java
@@ -1,6 +1,7 @@
 package bdi4jade.extension.remediation;
 
 import bdi4jade.annotation.Belief;
+import bdi4jade.core.BDIAgent;
 import bdi4jade.extension.remediation.graph.CauseEffectKnowledgeModel;
 import bdi4jade.extension.remediation.reasoning.RemediationOptionGenerationFunction;
 import bdi4jade.extension.remediation.reasoning.RemediationPlanSelectionStrategy;
@@ -16,7 +17,8 @@ public class RemediationCapability extends RevertingCapability {
 	@Belief(name = ResourcePreferences.NAME)
 	protected ResourcePreferences preferences = new ResourcePreferences();
 
-	public RemediationCapability() {
+	public RemediationCapability(BDIAgent agent) {
+		super(agent);
 		setOptionGenerationFunction(new RemediationOptionGenerationFunction(this));
 		setPlanSelectionStrategy(new RemediationPlanSelectionStrategy(this));
 	}
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 524f8c8..91c32cc 100644
--- a/bdi-jade-extensions/src/bdi4jade/extension/undo/reasoning/RevertingOptionGenerationFunction.java
+++ b/bdi-jade-extensions/src/bdi4jade/extension/undo/reasoning/RevertingOptionGenerationFunction.java
@@ -33,6 +33,7 @@ import bdi4jade.extension.undo.GoalAchievementMetadata;
 import bdi4jade.extension.undo.RevertingCapability;
 import bdi4jade.goal.Goal;
 import bdi4jade.goal.PredicateGoal;
+import bdi4jade.reasoning.AbstractReasoningStrategy;
 import bdi4jade.reasoning.OptionGenerationFunction;
 
 /**
@@ -42,9 +43,7 @@ import bdi4jade.reasoning.OptionGenerationFunction;
  * 
  * @author João Faccin
  */
-public class RevertingOptionGenerationFunction implements OptionGenerationFunction {
-
-	private Capability capability;
+public class RevertingOptionGenerationFunction extends AbstractReasoningStrategy implements OptionGenerationFunction {
 
 	/**
 	 * Initializes a new option generation function and sets its related capability.
@@ -115,22 +114,4 @@ public class RevertingOptionGenerationFunction implements OptionGenerationFuncti
 
 		return reversionGoals;
 	}
-
-	/*
-	 * (non-Javadoc)
-	 * 
-	 * @see
-	 * bdi4jade.reasoning.ReasoningStrategy#setCapability(bdi4jade.core.Capability)
-	 */
-	@Override
-	public void setCapability(Capability capability) {
-		if (this.capability != null) {
-			if (!this.capability.equals(capability)) {
-				throw new IllegalArgumentException(
-						"This reasoning strategy is already associated with another capability.");
-			}
-		}
-		this.capability = capability;
-	}
-
 }
diff --git a/bdi-jade-extensions/src/bdi4jade/extension/undo/RevertingCapability.java b/bdi-jade-extensions/src/bdi4jade/extension/undo/RevertingCapability.java
index c249f9d..0c01ff7 100644
--- a/bdi-jade-extensions/src/bdi4jade/extension/undo/RevertingCapability.java
+++ b/bdi-jade-extensions/src/bdi4jade/extension/undo/RevertingCapability.java
@@ -27,6 +27,7 @@ import java.util.List;
 import java.util.Map;
 
 import bdi4jade.belief.PredicateBelief;
+import bdi4jade.core.BDIAgent;
 import bdi4jade.core.Capability;
 import bdi4jade.core.Intention;
 import bdi4jade.event.BeliefEvent;
@@ -62,11 +63,11 @@ public class RevertingCapability extends Capability implements BeliefListener, G
 	 * Creates a new capability and sets {@link RevertingOptionGenerationFunction}
 	 * as its default option generation function.
 	 */
-	public RevertingCapability() {
+	public RevertingCapability(BDIAgent agent) {
 		this.gams = new HashMap<>();
 		this.parentGoals = new HashMap<>();
 		setOptionGenerationFunction(new RevertingOptionGenerationFunction(this));
-		this.getMyAgent().addGoalListener(this);
+		agent.addGoalListener(this);
 		this.getBeliefBase().addBeliefListener(this);
 	}
 
diff --git a/bdi-jade-test/src/bdi4jade/examples/undo/log4j.properties b/bdi-jade-test/src/bdi4jade/examples/undo/log4j.properties
new file mode 100644
index 0000000..4d04bcf
--- /dev/null
+++ b/bdi-jade-test/src/bdi4jade/examples/undo/log4j.properties
@@ -0,0 +1,41 @@
+#
+# Log4J Settings for log4j 1.2.x (via jakarta-commons-logging)
+#
+# The five logging levels used by Log are (in order):
+#
+#   1. DEBUG (the least serious)
+#   2. INFO
+#   3. WARN
+#   4. ERROR
+#   5. FATAL (the most serious)
+
+
+# Set root logger level to WARN and append to stdout
+log4j.rootLogger=WARN
+
+#log4j.appender.stdout=org.apache.log4j.ConsoleAppender
+#log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
+
+# Pattern to output the caller's file name and line number.
+#log4j.appender.stdout.layout.ConversionPattern=%d{HH:mm:ss,SSS} %5p (%c{1}:%L) - %m%n
+
+# Print only messages of level ERROR or above in the package noModule.
+log4j.logger.noModule=FATAL
+
+# OpenSymphony Stuff
+log4j.logger.com.opensymphony=FATAL
+log4j.logger.org.apache.struts2=FATAL
+
+# Spring Stuff
+log4j.logger.org.springframework=FATAL
+
+#log4j.logger.bdi4jade=WARN
+#log4j.logger.bdi4jade.examples=DEBUG
+#log4j.logger.bdi4jade.extension=DEBUG, fileOut
+#log4j.logger.com.paradox.braess=INFO, fileOut
+log4j.logger.bdi4jade.examples.undo=DEBUG, fileOut
+
+log4j.appender.fileOut =org.apache.log4j.RollingFileAppender
+log4j.appender.fileOut.File=results.log
+log4j.appender.fileOut.layout=org.apache.log4j.PatternLayout
+log4j.appender.fileOut.layout.ConversionPattern=%m%n
\ No newline at end of file
diff --git a/bdi-jade-test/src/bdi4jade/examples/undo/ManagementCapability.java b/bdi-jade-test/src/bdi4jade/examples/undo/ManagementCapability.java
index f85ea48..b3dcd79 100644
--- a/bdi-jade-test/src/bdi4jade/examples/undo/ManagementCapability.java
+++ b/bdi-jade-test/src/bdi4jade/examples/undo/ManagementCapability.java
@@ -1,8 +1,13 @@
 package bdi4jade.examples.undo;
 
+import java.util.ArrayList;
+
 import bdi4jade.annotation.Belief;
 import bdi4jade.belief.PredicateBelief;
 import bdi4jade.belief.TransientPredicate;
+import bdi4jade.core.BDIAgent;
+import bdi4jade.core.Capability;
+import bdi4jade.core.GoalUpdateSet;
 import bdi4jade.examples.undo.domain.CO;
 import bdi4jade.examples.undo.domain.House;
 import bdi4jade.examples.undo.domain.predicate.Abnormal;
@@ -11,8 +16,8 @@ import bdi4jade.examples.undo.domain.predicate.Locked;
 import bdi4jade.examples.undo.domain.predicate.On;
 import bdi4jade.examples.undo.domain.predicate.Open;
 import bdi4jade.examples.undo.domain.predicate.TakeOff;
-import bdi4jade.examples.undo.goal.NormalizeCOGoal;
 import bdi4jade.examples.undo.plan.EvacuateAndVentilatePlanBody;
+import bdi4jade.examples.undo.plan.NotifyAbnormalCOPlanBody;
 import bdi4jade.examples.undo.plan.request.RequestDeviceClosePlanBody;
 import bdi4jade.examples.undo.plan.request.RequestDeviceLockPlanBody;
 import bdi4jade.examples.undo.plan.request.RequestDeviceOffPlanBody;
@@ -21,47 +26,56 @@ import bdi4jade.examples.undo.plan.request.RequestDeviceOpenPlanBody;
 import bdi4jade.examples.undo.plan.request.RequestDeviceShutdownPlanBody;
 import bdi4jade.examples.undo.plan.request.RequestDeviceTakeOffPlanBody;
 import bdi4jade.examples.undo.plan.request.RequestDeviceUnlockPlanBody;
-import bdi4jade.extension.undo.RevertingCapability;
+import bdi4jade.extension.remediation.RemediationCapability;
+import bdi4jade.extension.remediation.graph.CauseEffectRelationship;
+import bdi4jade.extension.remediation.logics.Fact;
+import bdi4jade.extension.remediation.reasoning.RemediationOptionGenerationFunction;
 import bdi4jade.goal.GoalTemplateFactory;
+import bdi4jade.goal.PredicateGoal;
 import bdi4jade.plan.DefaultPlan;
 import bdi4jade.plan.Plan;
+import bdi4jade.reasoning.DefaultBeliefRevisionStrategy;
+import jade.core.AID;
+import jade.lang.acl.ACLMessage;
+import jade.lang.acl.MessageTemplate;
 
 /**
  * @author jgfaccin
  *
  */
-public class ManagementCapability extends RevertingCapability {
+public class ManagementCapability extends RemediationCapability {
 
 	private static final long serialVersionUID = -1971498055603790248L;
 
 	// Neighbours
 	@Belief
-	String alarmAgent;
+	private String alarmAgent;
+	@Belief
+	private String detectorAgent;
 	@Belief
-	String doorsAgent;
+	private String doorsAgent;
 	@Belief
-	String fansAgent;
+	private String fansAgent;
 	@Belief
-	String lightsAgent;
+	private String lightsAgent;
 	@Belief
-	String valveAgent;
+	private String valveAgent;
 	@Belief
-	String windowsAgent;
+	private String windowsAgent;
 
 	// Device Predicates
-	PredicateBelief<TakeOff> alarmTakeOff = new TransientPredicate<>(new TakeOff(House.ALARM), false);
-	PredicateBelief<Locked> doorsUnlock = new TransientPredicate<>(new Locked(House.DOORS), true);
-	PredicateBelief<On> fansOn = new TransientPredicate<On>(new On(House.FANS), false);
-	PredicateBelief<Leak> leakingWaterHeater = new TransientPredicate<Leak>(new Leak(House.WATER_HEATER), false);
-	PredicateBelief<On> lightsOn = new TransientPredicate<>(new On(House.LIGHTS), false);
-	PredicateBelief<Open> valveOpen = new TransientPredicate<Open>(new Open(House.VALVE), false);
-	PredicateBelief<Open> windowsOpen = new TransientPredicate<Open>(new Open(House.WINDOWS), false);
-	PredicateBelief<Abnormal> abnormalCO = new TransientPredicate<Abnormal>(new Abnormal(CO.getInstance()), false);
+	private PredicateBelief<TakeOff> alarmTakeOff;
+	private PredicateBelief<Locked> doorsUnlock;
+	private PredicateBelief<On> fansOn;
+	private PredicateBelief<Leak> leakingWaterHeater;
+	private PredicateBelief<On> lightsOn;
+	private PredicateBelief<Open> valveOpen;
+	private PredicateBelief<Open> windowsOpen;
+	private PredicateBelief<Abnormal> abnormalCO;
 
 	// Plans
 	@bdi4jade.annotation.Plan
 	private Plan evacuateAndVentilatePlan;
-
 	@bdi4jade.annotation.Plan
 	private Plan requestDeviceTakeOffPlan;
 	@bdi4jade.annotation.Plan
@@ -79,45 +93,116 @@ public class ManagementCapability extends RevertingCapability {
 	@bdi4jade.annotation.Plan
 	private Plan requestDeviceClosePlan;
 
-	public ManagementCapability(String alarmAgent, String valveAgent, String doorsAgent, String fansAgent,
-			String lightsAgent, String windowsAgent) {
+	public ManagementCapability(BDIAgent agent, String alarmAgent, String detectorAgent, String doorsAgent, String fansAgent,
+			String lightsAgent, String valveAgent, String windowsAgent) {
+		super(agent);
 		this.alarmAgent = alarmAgent;
-		this.valveAgent = valveAgent;
+		this.detectorAgent = detectorAgent;
 		this.doorsAgent = doorsAgent;
 		this.fansAgent = fansAgent;
 		this.lightsAgent = lightsAgent;
+		this.valveAgent = valveAgent;
 		this.windowsAgent = windowsAgent;
 
+		setBeliefRevisionStrategy(new MyBeliefRevisionStrategy());
+		setOptionGenerationFunction(new MyOptionGenerationFunction(this));
+		
+		initializeBeliefs();
+		initializeCauseEffectKnowledgeModel();
 		initializePlans();
-		initializeCauseEffectRelationship();
 	}
 
-	private void initializePlans() {
+	private void initializeBeliefs() {
+		ArrayList<PredicateBelief<?>> beliefs = new ArrayList<>();
+		this.alarmTakeOff = new TransientPredicate<>(new TakeOff(House.ALARM), false);
+		beliefs.add(alarmTakeOff);
+		this.doorsUnlock = new TransientPredicate<>(new Locked(House.DOORS), true);
+		beliefs.add(doorsUnlock);
+		this.fansOn = new TransientPredicate<On>(new On(House.FANS), false);
+		beliefs.add(fansOn);
+		this.leakingWaterHeater = new TransientPredicate<Leak>(new Leak(House.WATER_HEATER), false);
+		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);
+		beliefs.add(valveOpen);
+		this.windowsOpen = new TransientPredicate<Open>(new Open(House.WINDOWS), false);
+		beliefs.add(windowsOpen);
+		this.abnormalCO = new TransientPredicate<Abnormal>(new Abnormal(CO.getInstance()), false);
+		beliefs.add(abnormalCO);
+
+		for (PredicateBelief<?> predicateBelief : beliefs) {
+			beliefBase.addBelief(predicateBelief);
+		}
+	}
 
+	private void initializeCauseEffectKnowledgeModel() {
+		CauseEffectRelationship cer = new CauseEffectRelationship(new Fact(new Abnormal(CO.getInstance()), true));
+		cer.addOptionalCause(new Fact(new Leak(House.WATER_HEATER), true));
+		causeEffectKnowledgeModel.addCauseEffectRelationship(cer);
+	}
+
+	private void initializePlans() {
 		this.requestDeviceTakeOffPlan = new DefaultPlan(
 				GoalTemplateFactory.hasBeliefOfTypeWithValue(TakeOff.class, true), RequestDeviceTakeOffPlanBody.class);
 		this.requestDeviceShutdownPlan = new DefaultPlan(
-				GoalTemplateFactory.hasBeliefOfTypeWithValue(TakeOff.class, false), RequestDeviceShutdownPlanBody.class);
-		
-		this.requestDeviceOnPlan = new DefaultPlan(
-				GoalTemplateFactory.hasBeliefOfTypeWithValue(On.class, true), RequestDeviceOnPlanBody.class);
-		this.requestDeviceOffPlan = new DefaultPlan(
-				GoalTemplateFactory.hasBeliefOfTypeWithValue(On.class, false), RequestDeviceOffPlanBody.class);
-		
+				GoalTemplateFactory.hasBeliefOfTypeWithValue(TakeOff.class, false),
+				RequestDeviceShutdownPlanBody.class);
+
+		this.requestDeviceOnPlan = new DefaultPlan(GoalTemplateFactory.hasBeliefOfTypeWithValue(On.class, true),
+				RequestDeviceOnPlanBody.class);
+		this.requestDeviceOffPlan = new DefaultPlan(GoalTemplateFactory.hasBeliefOfTypeWithValue(On.class, false),
+				RequestDeviceOffPlanBody.class);
+
 		this.requestDeviceUnlockPlan = new DefaultPlan(
 				GoalTemplateFactory.hasBeliefOfTypeWithValue(Locked.class, false), RequestDeviceUnlockPlanBody.class);
-		this.requestDeviceLockPlan = new DefaultPlan(
-				GoalTemplateFactory.hasBeliefOfTypeWithValue(Locked.class, true), RequestDeviceLockPlanBody.class);
-		
-		this.requestDeviceOpenPlan = new DefaultPlan(
-				GoalTemplateFactory.hasBeliefOfTypeWithValue(Open.class, true), RequestDeviceOpenPlanBody.class);
-		this.requestDeviceClosePlan = new DefaultPlan(
-				GoalTemplateFactory.hasBeliefOfTypeWithValue(Open.class, false), RequestDeviceClosePlanBody.class);
-		
-		this.evacuateAndVentilatePlan = new DefaultPlan(NormalizeCOGoal.class, EvacuateAndVentilatePlanBody.class);
+		this.requestDeviceLockPlan = new DefaultPlan(GoalTemplateFactory.hasBeliefOfTypeWithValue(Locked.class, true),
+				RequestDeviceLockPlanBody.class);
+
+		this.requestDeviceOpenPlan = new DefaultPlan(GoalTemplateFactory.hasBeliefOfTypeWithValue(Open.class, true),
+				RequestDeviceOpenPlanBody.class);
+		this.requestDeviceClosePlan = new DefaultPlan(GoalTemplateFactory.hasBeliefOfTypeWithValue(Open.class, false),
+				RequestDeviceClosePlanBody.class);
+
+		this.evacuateAndVentilatePlan = new DefaultPlan(
+				GoalTemplateFactory.hasBeliefOfTypeWithValue(Abnormal.class, false),
+				EvacuateAndVentilatePlanBody.class);
 	}
 
-	private void initializeCauseEffectRelationship() {
+	class MyBeliefRevisionStrategy extends DefaultBeliefRevisionStrategy {
+
+		private MessageTemplate mt;
+
+		@Override
+		public void reviewBeliefs() {
+			super.reviewBeliefs();
+			this.mt = MessageTemplate.MatchSender(new AID(detectorAgent, false));
+			ACLMessage notificationMsg = getMyAgent().receive(mt);
+			if (notificationMsg != null) {
+				if (notificationMsg.getContent().equals(NotifyAbnormalCOPlanBody.ABNORMAL_CO)) {
+					abnormalCO.setValue(true);
+					leakingWaterHeater.setValue(true);
+				} else {
+					abnormalCO.setValue(false);
+				}
+			}
+		}
+
+	}
+	
+	class MyOptionGenerationFunction extends RemediationOptionGenerationFunction {
 
+		public MyOptionGenerationFunction(Capability capability) {
+			super(ManagementCapability.this);
+		}
+	
+		@Override
+		public void generateGoals(GoalUpdateSet goalUpdateSet) {
+			if (abnormalCO.getValue()) {
+				goalUpdateSet.generateGoal(new PredicateGoal<Abnormal>(new Abnormal(CO.getInstance()), false));
+			}
+			
+			super.generateGoals(goalUpdateSet);
+		}
 	}
 }
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 50169c7..8c44a15 100644
--- a/bdi-jade-test/src/bdi4jade/examples/undo/plan/AnswerRequestPlanBody.java
+++ b/bdi-jade-test/src/bdi4jade/examples/undo/plan/AnswerRequestPlanBody.java
@@ -7,6 +7,11 @@ import org.apache.commons.logging.LogFactory;
 
 import bdi4jade.annotation.Parameter;
 import bdi4jade.annotation.Parameter.Direction;
+import bdi4jade.examples.undo.domain.CO;
+import bdi4jade.examples.undo.plan.request.RequestDeviceClosePlanBody;
+import bdi4jade.examples.undo.plan.request.RequestDeviceOffPlanBody;
+import bdi4jade.examples.undo.plan.request.RequestDeviceOnPlanBody;
+import bdi4jade.examples.undo.plan.request.RequestDeviceOpenPlanBody;
 import bdi4jade.plan.Plan.EndState;
 import bdi4jade.plan.planbody.AbstractPlanBody;
 import jade.lang.acl.ACLMessage;
@@ -34,6 +39,8 @@ public class AnswerRequestPlanBody extends AbstractPlanBody {
 			Random random = new Random(System.currentTimeMillis());
 			Thread.sleep(random.nextInt(10) * 1000);
 
+			act(requestMsg);
+
 			this.myAgent.send(reply);
 			log.info("Reply sent to agent " + requestMsg.getSender().getName() + "!");
 			setEndState(EndState.SUCCESSFUL);
@@ -47,4 +54,25 @@ public class AnswerRequestPlanBody extends AbstractPlanBody {
 		this.requestMsg = requestMsg;
 	}
 
+	private void act(ACLMessage requestMsg) {
+		switch (requestMsg.getContent()) {
+		case RequestDeviceOnPlanBody.MSG_FANS_CONTENT:
+			CO.getInstance().setFansOn(true);
+			break;
+		case RequestDeviceOpenPlanBody.MSG_WINDOWS_CONTENT:
+			CO.getInstance().setOpenWindows(true);
+			break;
+		case RequestDeviceOffPlanBody.MSG_FANS_CONTENT:
+			CO.getInstance().setFansOn(false);
+			break;
+		case RequestDeviceClosePlanBody.MSG_WINDOWS_CONTENT:
+			CO.getInstance().setOpenWindows(false);
+			break;
+		case RequestDeviceClosePlanBody.MSG_VALVE_CONTENT:
+			CO.getInstance().setLeaking(false);
+		default:
+			break;
+		}
+	}
+
 }
diff --git a/bdi-jade-test/src/bdi4jade/examples/undo/plan/EvacuateAndVentilatePlanBody.java b/bdi-jade-test/src/bdi4jade/examples/undo/plan/EvacuateAndVentilatePlanBody.java
index 4429b31..3969bcf 100644
--- a/bdi-jade-test/src/bdi4jade/examples/undo/plan/EvacuateAndVentilatePlanBody.java
+++ b/bdi-jade-test/src/bdi4jade/examples/undo/plan/EvacuateAndVentilatePlanBody.java
@@ -1,6 +1,12 @@
 package bdi4jade.examples.undo.plan;
 
+import bdi4jade.examples.undo.domain.House;
+import bdi4jade.examples.undo.domain.predicate.Locked;
+import bdi4jade.examples.undo.domain.predicate.On;
+import bdi4jade.examples.undo.domain.predicate.Open;
+import bdi4jade.examples.undo.domain.predicate.TakeOff;
 import bdi4jade.extension.undo.RevertingPlanBody;
+import bdi4jade.goal.PredicateGoal;
 
 /**
  * @author jgfaccin
@@ -12,7 +18,10 @@ public class EvacuateAndVentilatePlanBody extends RevertingPlanBody {
 
 	@Override
 	protected void execute() {
-		
+		dispatchSubgoal(new PredicateGoal<TakeOff>(new TakeOff(House.ALARM), true));
+		dispatchSubgoal(new PredicateGoal<On>(new On(House.LIGHTS), true));
+		dispatchSubgoal(new PredicateGoal<Locked>(new Locked(House.DOORS), false));
+		dispatchSubgoal(new PredicateGoal<Open>(new Open(House.WINDOWS), true));
+		dispatchSubgoal(new PredicateGoal<On>(new On(House.FANS), true));
 	}
-
 }
diff --git a/bdi-jade-test/src/bdi4jade/examples/undo/plan/NotifyAbnormalCOPlanBody.java b/bdi-jade-test/src/bdi4jade/examples/undo/plan/NotifyAbnormalCOPlanBody.java
new file mode 100644
index 0000000..582dada
--- /dev/null
+++ b/bdi-jade-test/src/bdi4jade/examples/undo/plan/NotifyAbnormalCOPlanBody.java
@@ -0,0 +1,82 @@
+//----------------------------------------------------------------------------
+// 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/prosoft/bdi4jade/
+//
+//----------------------------------------------------------------------------
+
+package bdi4jade.examples.undo.plan;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import bdi4jade.belief.Belief;
+import bdi4jade.examples.undo.domain.CO;
+import bdi4jade.plan.planbody.AbstractPlanBody;
+import jade.core.AID;
+import jade.lang.acl.ACLMessage;
+
+/**
+ * @author jgfaccin
+ *
+ */
+public class NotifyAbnormalCOPlanBody extends AbstractPlanBody {
+
+	private static final long serialVersionUID = 6474747389538222991L;
+
+	private static final Log log = LogFactory.getLog(NotifyAbnormalCOPlanBody.class);
+	
+	private boolean lastStatus = false;
+
+	@bdi4jade.annotation.Belief
+	private Belief<String, String> managerAgent;
+
+	public static final String ABNORMAL_CO = "ABNORMAL_CO";
+	public static final String NORMAL_CO = "NORMAL_CO";
+	private final String receiver = "MANAGER";
+	
+	@Override
+	public void action() {
+		while(true) {
+			CO co = CO.getInstance();
+			if (co.getGasConcentration() > 50 & !lastStatus) {
+				notifyManager(ABNORMAL_CO);
+				this.lastStatus = true;
+			} else {
+				if(co.getGasConcentration() <= 50 & lastStatus) {
+					notifyManager(NORMAL_CO);
+					this.lastStatus = false;
+				}
+			}
+			try {
+				Thread.sleep(5000);
+			} catch (InterruptedException e) {
+				e.printStackTrace();
+			}
+		}
+	}
+	
+	private void notifyManager(String msgContent) {
+		ACLMessage msg = new ACLMessage(ACLMessage.INFORM);
+		msg.setContent(msgContent);
+		msg.addReceiver(new AID(receiver, false));
+		msg.setConversationId("cin" + System.currentTimeMillis());
+		myAgent.send(msg);
+		log.info("Notification [" + msgContent + "] sent to agent " + receiver + "!");
+	}
+}
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 037fc15..480e777 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
@@ -25,8 +25,8 @@ public class RequestDeviceClosePlanBody extends RevertingPlanBody {
 
 	private static final Log log = LogFactory.getLog(RequestDeviceClosePlanBody.class);
 
-	public static final String MSG_WINDOWS_CONTENT = "WINDOWS_OPEN";
-	public static final String MSG_VALVE_CONTENT = "VALVE_OPEN";
+	public static final String MSG_WINDOWS_CONTENT = "WINDOWS_CLOSE";
+	public static final String MSG_VALVE_CONTENT = "VALVE_CLOSE";
 
 	private MessageTemplate mt;
 	private boolean sent = false;
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 81cd5d7..c518830 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
@@ -25,8 +25,8 @@ public class RequestDeviceOffPlanBody extends RevertingPlanBody {
 	
 	private static final Log log = LogFactory.getLog(RequestDeviceOffPlanBody.class);
 
-	public static final String MSG_FANS_CONTENT = "FANS_ON";
-	public static final String MSG_LIGHTS_CONTENT = "LIGHTS_ON";
+	public static final String MSG_FANS_CONTENT = "FANS_OFF";
+	public static final String MSG_LIGHTS_CONTENT = "LIGHTS_OFF";
 
 	@bdi4jade.annotation.Belief
 	private Belief<String, String> fansAgent;
diff --git a/bdi-jade-test/src/bdi4jade/examples/undo/Runner.java b/bdi-jade-test/src/bdi4jade/examples/undo/Runner.java
new file mode 100644
index 0000000..e010af9
--- /dev/null
+++ b/bdi-jade-test/src/bdi4jade/examples/undo/Runner.java
@@ -0,0 +1,162 @@
+package bdi4jade.examples.undo;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.log4j.PropertyConfigurator;
+
+import bdi4jade.examples.undo.domain.CO;
+import bdi4jade.examples.undo.goal.MonitorCOGoal;
+import bdi4jade.examples.undo.plan.AnswerRequestPlanBody;
+import bdi4jade.examples.undo.plan.NotifyAbnormalCOPlanBody;
+import bdi4jade.examples.undo.plan.request.RequestDeviceClosePlanBody;
+import bdi4jade.examples.undo.plan.request.RequestDeviceLockPlanBody;
+import bdi4jade.examples.undo.plan.request.RequestDeviceOffPlanBody;
+import bdi4jade.examples.undo.plan.request.RequestDeviceOnPlanBody;
+import bdi4jade.examples.undo.plan.request.RequestDeviceOpenPlanBody;
+import bdi4jade.examples.undo.plan.request.RequestDeviceShutdownPlanBody;
+import bdi4jade.examples.undo.plan.request.RequestDeviceTakeOffPlanBody;
+import bdi4jade.examples.undo.plan.request.RequestDeviceUnlockPlanBody;
+import bdi4jade.plan.DefaultPlan;
+import jade.BootProfileImpl;
+import jade.core.ProfileImpl;
+import jade.lang.acl.MessageTemplate;
+import jade.wrapper.AgentContainer;
+import jade.wrapper.AgentController;
+import jade.wrapper.PlatformController;
+
+/**
+ * @author jgfaccin
+ *
+ */
+public class Runner {
+
+	public static void main(String[] args) {
+		PropertyConfigurator.configure(Runner.class.getResource("log4j.properties"));
+		Runner runner = new Runner();
+		runner.run();
+	}
+
+	private final Log log;
+	private ProfileImpl bootProfile;
+	private jade.core.Runtime runtime;
+	private PlatformController controller;
+
+	private SmartHomeAgent alarmAgent;
+	private SmartHomeAgent detectorAgent;
+	private SmartHomeAgent doorsAgent;
+	private SmartHomeAgent fansAgent;
+	private SmartHomeAgent lightsAgent;
+	private SmartHomeAgent managerAgent;
+	private SmartHomeAgent valveAgent;
+	private SmartHomeAgent windowsAgent;
+
+	public Runner() {
+		this.log = LogFactory.getLog(this.getClass());
+
+		List<String> params = new ArrayList<String>();
+		params.add("-gui");
+		params.add("-detect-main:false");
+
+		this.bootProfile = new BootProfileImpl(params.toArray(new String[0]));
+		this.runtime = jade.core.Runtime.instance();
+		this.controller = runtime.createMainContainer(bootProfile);
+
+		setupAgents();
+
+		ArrayList<SmartHomeAgent> agents = new ArrayList<>();
+		agents.add(alarmAgent);
+		agents.add(detectorAgent);
+		agents.add(doorsAgent);
+		agents.add(fansAgent);
+		agents.add(lightsAgent);
+		agents.add(managerAgent);
+		agents.add(valveAgent);
+		agents.add(windowsAgent);
+
+		initializeAgents(agents);
+	}
+
+	private void initializeAgents(ArrayList<SmartHomeAgent> agents) {
+		for (SmartHomeAgent agent : agents) {
+			try {
+				AgentController ac = ((AgentContainer) controller).acceptNewAgent(agent.getCustomName(), agent);
+				ac.start();
+			} catch (Exception e) {
+				System.out.println(e);
+			}
+		}
+	}
+	
+	public void run() {
+		this.detectorAgent.addGoal(new MonitorCOGoal());
+		CO co = CO.getInstance();
+		Thread gas = new Thread(co);
+		gas.start();
+		try {
+			Thread.sleep(10000);
+		} catch (InterruptedException e) {
+			// TODO Auto-generated catch block
+			e.printStackTrace();
+		}
+		co.setLeaking(true);
+
+	}
+
+	private void setupAgents() {
+		this.detectorAgent = new SmartHomeAgent("DETECTOR");
+		this.detectorAgent.getCapability().getPlanLibrary()
+				.addPlan(new DefaultPlan(MonitorCOGoal.class, NotifyAbnormalCOPlanBody.class));
+
+		this.alarmAgent = new SmartHomeAgent("ALARM");
+		this.alarmAgent.getCapability().getPlanLibrary()
+				.addPlan(new DefaultPlan(
+						MessageTemplate.and(MessageTemplate.MatchContent(RequestDeviceTakeOffPlanBody.MSG_CONTENT),
+								MessageTemplate.MatchContent(RequestDeviceShutdownPlanBody.MSG_CONTENT)),
+						AnswerRequestPlanBody.class));
+
+		this.lightsAgent = new SmartHomeAgent("LIGHTS");
+		this.lightsAgent.getCapability().getPlanLibrary()
+				.addPlan(new DefaultPlan(
+						MessageTemplate.and(MessageTemplate.MatchContent(RequestDeviceOnPlanBody.MSG_LIGHTS_CONTENT),
+								MessageTemplate.MatchContent(RequestDeviceOffPlanBody.MSG_LIGHTS_CONTENT)),
+						AnswerRequestPlanBody.class));
+
+		this.doorsAgent = new SmartHomeAgent("DOORS");
+		this.doorsAgent.getCapability().getPlanLibrary()
+				.addPlan(new DefaultPlan(
+						MessageTemplate.and(MessageTemplate.MatchContent(RequestDeviceUnlockPlanBody.MSG_CONTENT),
+								MessageTemplate.MatchContent(RequestDeviceLockPlanBody.MSG_CONTENT)),
+						AnswerRequestPlanBody.class));
+
+		this.windowsAgent = new SmartHomeAgent("WINDOWS");
+		this.windowsAgent.getCapability().getPlanLibrary()
+				.addPlan(new DefaultPlan(
+						MessageTemplate.and(MessageTemplate.MatchContent(RequestDeviceOpenPlanBody.MSG_WINDOWS_CONTENT),
+								MessageTemplate.MatchContent(RequestDeviceClosePlanBody.MSG_WINDOWS_CONTENT)),
+						AnswerRequestPlanBody.class));
+
+		this.fansAgent = new SmartHomeAgent("FANS");
+		this.fansAgent.getCapability().getPlanLibrary()
+				.addPlan(new DefaultPlan(
+						MessageTemplate.and(MessageTemplate.MatchContent(RequestDeviceOnPlanBody.MSG_FANS_CONTENT),
+								MessageTemplate.MatchContent(RequestDeviceOffPlanBody.MSG_FANS_CONTENT)),
+						AnswerRequestPlanBody.class));
+
+		this.valveAgent = new SmartHomeAgent("VALVE");
+		this.valveAgent.getCapability().getPlanLibrary()
+				.addPlan(new DefaultPlan(
+						MessageTemplate.and(MessageTemplate.MatchContent(RequestDeviceOpenPlanBody.MSG_VALVE_CONTENT),
+								MessageTemplate.MatchContent(RequestDeviceClosePlanBody.MSG_VALVE_CONTENT)),
+						AnswerRequestPlanBody.class));
+
+		this.managerAgent = new SmartHomeAgent("MANAGER");
+		this.managerAgent.setCapability(new ManagementCapability(managerAgent, alarmAgent.getCustomName(), detectorAgent.getCustomName(),
+						doorsAgent.getCustomName(), fansAgent.getCustomName(), lightsAgent.getCustomName(),
+						valveAgent.getCustomName(), windowsAgent.getCustomName()));
+
+	}
+
+}
diff --git a/bdi-jade-test/src/bdi4jade/examples/undo/SmartHomeAgent.java b/bdi-jade-test/src/bdi4jade/examples/undo/SmartHomeAgent.java
new file mode 100644
index 0000000..23368d4
--- /dev/null
+++ b/bdi-jade-test/src/bdi4jade/examples/undo/SmartHomeAgent.java
@@ -0,0 +1,30 @@
+package bdi4jade.examples.undo;
+
+import bdi4jade.core.Capability;
+import bdi4jade.core.SingleCapabilityAgent;
+
+/**
+ * @author jgfaccin
+ *
+ */
+public class SmartHomeAgent extends SingleCapabilityAgent {
+
+	private static final long serialVersionUID = 3958283995451069802L;
+
+	private String customName;
+	
+
+	public SmartHomeAgent(String customName) {
+		super();
+		this.customName = customName;
+	}
+	
+	public SmartHomeAgent(String customName, Capability capability) {
+		super(capability);
+		this.customName = customName;
+	}
+	
+	public String getCustomName() {
+		return customName;
+	}
+}