bdi4jade
Changes
bdi-jade/.classpath 24(+12 -12)
bdi-jade/.project 4(+2 -2)
bdi-jade/src/bdi4jade/core/AbstractBDIAgent.java 103(+47 -56)
bdi-jade/src/bdi4jade/core/BDIAgent.java 36(+22 -14)
bdi-jade/src/bdi4jade/goal/NestedGoal.java 43(+43 -0)
bdi-jade/src/bdi4jade/plan/DefaultPlan.java 68(+35 -33)
bdi-jade-extensions/.classpath 2(+1 -1)
bdi-jade-extensions/src/bdi4jade/extension/palliative/graph/CauseEffectKnowledgeModel.java 42(+42 -0)
bdi-jade-extensions/src/bdi4jade/extension/palliative/logics/BinaryLogicalExpression.java 73(+73 -0)
bdi-jade-extensions/src/bdi4jade/extension/palliative/reasoning/PalliativeOptionGenerationFunction.java 254(+254 -0)
Details
bdi-jade/.classpath 24(+12 -12)
diff --git a/bdi-jade/.classpath b/bdi-jade/.classpath
index c21aed9..cbac2e1 100644
--- a/bdi-jade/.classpath
+++ b/bdi-jade/.classpath
@@ -1,12 +1,12 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<classpath>
- <classpathentry kind="src" path="src"/>
- <classpathentry kind="src" path="extensions-src"/>
- <classpathentry kind="src" path="examples-src"/>
- <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.7"/>
- <classpathentry kind="lib" path="lib/jade-4.3.2.jar"/>
- <classpathentry kind="lib" path="lib/commons-logging-1.1.3.jar"/>
- <classpathentry kind="lib" path="lib/log4j-1.2.17.jar"/>
- <classpathentry kind="lib" path="/bdi-jade-extensions/lib/weka.jar"/>
- <classpathentry kind="output" path="bin"/>
-</classpath>
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+ <classpathentry kind="src" path="src"/>
+ <classpathentry kind="src" path="extensions-src"/>
+ <classpathentry kind="src" path="examples-src"/>
+ <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.7"/>
+ <classpathentry kind="lib" path="lib/jade-4.3.2.jar"/>
+ <classpathentry kind="lib" path="lib/commons-logging-1.1.3.jar"/>
+ <classpathentry kind="lib" path="lib/log4j-1.2.17.jar"/>
+ <classpathentry kind="lib" path="/bdi-jade-extensions/lib/weka.jar"/>
+ <classpathentry kind="output" path="bin"/>
+</classpath>
bdi-jade/.project 4(+2 -2)
diff --git a/bdi-jade/.project b/bdi-jade/.project
index 4125a50..d900c35 100644
--- a/bdi-jade/.project
+++ b/bdi-jade/.project
@@ -18,12 +18,12 @@
<link>
<name>examples-src</name>
<type>2</type>
- <location>D:/ingrid/Workspaces/mas-research/bdi4jade/bdi-jade-test/src</location>
+ <location>/Users/ingridnunes/Documents/workspaces/aamas-2107/bdi4jade/bdi-jade-test/src</location>
</link>
<link>
<name>extensions-src</name>
<type>2</type>
- <location>D:/ingrid/Workspaces/mas-research/bdi4jade/bdi-jade-extensions/src</location>
+ <location>/Users/ingridnunes/Documents/workspaces/aamas-2107/bdi4jade/bdi-jade-extensions/src</location>
</link>
</linkedResources>
</projectDescription>
diff --git a/bdi-jade/src/bdi4jade/belief/DerivedPredicate.java b/bdi-jade/src/bdi4jade/belief/DerivedPredicate.java
index a7491f0..0293ee9 100644
--- a/bdi-jade/src/bdi4jade/belief/DerivedPredicate.java
+++ b/bdi-jade/src/bdi4jade/belief/DerivedPredicate.java
@@ -29,8 +29,7 @@ package bdi4jade.belief;
*
* @author Ingrid Nunes
*/
-public abstract class DerivedPredicate<K> extends DerivedBelief<K, Boolean>
- implements Predicate<K> {
+public abstract class DerivedPredicate<K> extends DerivedBelief<K, Boolean> implements PredicateBelief<K> {
private static final long serialVersionUID = -1551397656846999182L;
@@ -53,4 +52,17 @@ public abstract class DerivedPredicate<K> extends DerivedBelief<K, Boolean>
super(name);
}
+ @Override
+ public String toString() {
+ StringBuffer sb = new StringBuffer();
+ Boolean value = getValue();
+ if (value == null) {
+ sb.append("not ");
+ } else if (!value) {
+ sb.append("~");
+ }
+ sb.append(getName());
+ return sb.toString();
+ }
+
}
diff --git a/bdi-jade/src/bdi4jade/belief/TransientPredicate.java b/bdi-jade/src/bdi4jade/belief/TransientPredicate.java
index fe39162..b16fbb6 100644
--- a/bdi-jade/src/bdi4jade/belief/TransientPredicate.java
+++ b/bdi-jade/src/bdi4jade/belief/TransientPredicate.java
@@ -28,8 +28,7 @@ package bdi4jade.belief;
*
* @author Ingrid Nunes
*/
-public class TransientPredicate<K> extends TransientBelief<K, Boolean>
- implements Predicate<K> {
+public class TransientPredicate<K> extends TransientBelief<K, Boolean> implements PredicateBelief<K> {
private static final long serialVersionUID = -2315938302480821432L;
@@ -64,4 +63,16 @@ public class TransientPredicate<K> extends TransientBelief<K, Boolean>
super(name, value);
}
+ @Override
+ public String toString() {
+ StringBuffer sb = new StringBuffer();
+ if (getValue() == null) {
+ sb.append("not ");
+ } else if (!value) {
+ sb.append("~");
+ }
+ sb.append(getName());
+ return sb.toString();
+ }
+
}
bdi-jade/src/bdi4jade/core/AbstractBDIAgent.java 103(+47 -56)
diff --git a/bdi-jade/src/bdi4jade/core/AbstractBDIAgent.java b/bdi-jade/src/bdi4jade/core/AbstractBDIAgent.java
index 401ee41..67f68b6 100644
--- a/bdi-jade/src/bdi4jade/core/AbstractBDIAgent.java
+++ b/bdi-jade/src/bdi4jade/core/AbstractBDIAgent.java
@@ -22,11 +22,6 @@
package bdi4jade.core;
-import jade.core.Agent;
-import jade.core.behaviours.CyclicBehaviour;
-import jade.lang.acl.ACLMessage;
-import jade.proto.states.MsgReceiver;
-
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
@@ -57,6 +52,10 @@ import bdi4jade.reasoning.DefaultAgentDeliberationFunction;
import bdi4jade.reasoning.DefaultAgentOptionGenerationFunction;
import bdi4jade.reasoning.DefaultAgentPlanSelectionStrategy;
import bdi4jade.util.ReflectionUtils;
+import jade.core.Agent;
+import jade.core.behaviours.CyclicBehaviour;
+import jade.lang.acl.ACLMessage;
+import jade.proto.states.MsgReceiver;
/**
* This class is an abstract implementation of the {@link BDIAgent} interface.
@@ -119,36 +118,27 @@ public abstract class AbstractBDIAgent extends Agent implements BDIAgent {
GoalUpdateSet agentGoalUpdateSet = processIntentions(agentIntentions);
Map<Capability, GoalUpdateSet> capabilityGoalUpdateSets = new HashMap<>();
for (Capability capability : capabilities) {
- GoalUpdateSet capabilityGoalUpdateSet = processIntentions(capability
- .getIntentions());
- capabilityGoalUpdateSets.put(capability,
- capabilityGoalUpdateSet);
+ GoalUpdateSet capabilityGoalUpdateSet = processIntentions(capability.getIntentions());
+ capabilityGoalUpdateSets.put(capability, capabilityGoalUpdateSet);
}
// Generating new goals and choosing goals to drop
- optionGenerationFunction.generateGoals(agentGoalUpdateSet,
- capabilityGoalUpdateSets);
+ optionGenerationFunction.generateGoals(agentGoalUpdateSet, capabilityGoalUpdateSets);
// Adding generated goals
- for (GoalDescription goal : agentGoalUpdateSet
- .getGeneratedGoals()) {
+ for (GoalDescription goal : agentGoalUpdateSet.getGeneratedGoals()) {
try {
- Intention intention = addIntention(
- goal.getDispatcher(), goal.getGoal(),
- goal.getListener());
+ Intention intention = addIntention(goal.getDispatcher(), goal.getGoal(), goal.getListener());
if (intention != null)
agentGoalUpdateSet.addIntention(intention);
} catch (IllegalAccessException exc) {
log.error(exc);
}
}
- for (GoalUpdateSet goalUpdateSet : capabilityGoalUpdateSets
- .values()) {
- for (GoalDescription goal : goalUpdateSet
- .getGeneratedGoals()) {
+ for (GoalUpdateSet goalUpdateSet : capabilityGoalUpdateSets.values()) {
+ for (GoalDescription goal : goalUpdateSet.getGeneratedGoals()) {
try {
- Intention intention = addIntention(
- goal.getDispatcher(), goal.getGoal(),
+ Intention intention = addIntention(goal.getDispatcher(), goal.getGoal(),
goal.getListener());
if (intention != null)
goalUpdateSet.addIntention(intention);
@@ -159,21 +149,18 @@ public abstract class AbstractBDIAgent extends Agent implements BDIAgent {
}
// Removing dropped goals
- for (GoalDescription goal : agentGoalUpdateSet
- .getDroppedGoals()) {
+ for (GoalDescription goal : agentGoalUpdateSet.getDroppedGoals()) {
goal.getIntention().noLongerDesire();
fireGoalEvent(goal.getIntention());
agentIntentions.remove(goal.getIntention());
allIntentions.remove(goal.getGoal());
agentGoalUpdateSet.removeIntention(goal);
}
- for (GoalUpdateSet goalUpdateSet : capabilityGoalUpdateSets
- .values()) {
+ for (GoalUpdateSet goalUpdateSet : capabilityGoalUpdateSets.values()) {
for (GoalDescription goal : goalUpdateSet.getDroppedGoals()) {
goal.getIntention().noLongerDesire();
fireGoalEvent(goal.getIntention());
- goal.getDispatcher().removeIntention(
- goal.getIntention());
+ goal.getDispatcher().removeIntention(goal.getIntention());
allIntentions.remove(goal.getGoal());
goalUpdateSet.removeIntention(goal);
}
@@ -182,14 +169,12 @@ public abstract class AbstractBDIAgent extends Agent implements BDIAgent {
// Filtering options
Map<Capability, Set<GoalDescription>> capabilityGoals = new HashMap<>();
for (Capability capability : capabilityGoalUpdateSets.keySet()) {
- capabilityGoals.put(capability, capabilityGoalUpdateSets
- .get(capability).getCurrentGoals());
+ capabilityGoals.put(capability, capabilityGoalUpdateSets.get(capability).getCurrentGoals());
}
- Set<Goal> selectedGoals = deliberationFunction.filter(
- agentGoalUpdateSet.getCurrentGoals(), capabilityGoals);
+ Set<Goal> selectedGoals = deliberationFunction.filter(agentGoalUpdateSet.getCurrentGoals(),
+ capabilityGoals);
- log.trace("Selected goals to be intentions: "
- + selectedGoals.size());
+ log.trace("Selected goals to be intentions: " + selectedGoals.size());
for (Intention intention : allIntentions.values()) {
if (selectedGoals.contains(intention.getGoal())) {
intention.tryToAchive();
@@ -310,8 +295,7 @@ public abstract class AbstractBDIAgent extends Agent implements BDIAgent {
* bdi4jade.goal.Goal, bdi4jade.event.GoalListener)
*/
@Override
- public final boolean addGoal(Capability dispatcher, Goal goal,
- GoalListener goalListener) {
+ public final boolean addGoal(Capability dispatcher, Goal goal, GoalListener goalListener) {
try {
addIntention(dispatcher, goal, goalListener);
return true;
@@ -351,6 +335,22 @@ public abstract class AbstractBDIAgent extends Agent implements BDIAgent {
}
/**
+ * @see bdi4jade.core.BDIAgent#addGoalListener(bdi4jade.goal.Goal,
+ * bdi4jade.event.GoalListener)
+ */
+ @Override
+ public boolean addGoalListener(Goal goal, GoalListener goalListener) {
+ synchronized (allIntentions) {
+ Intention intention = this.allIntentions.get(goal);
+ if (intention != null) {
+ intention.addGoalListener(goalListener);
+ return true;
+ }
+ return false;
+ }
+ }
+
+ /**
* @see bdi4jade.core.BDIAgent#addGoalListener(bdi4jade.event.GoalListener)
*/
@Override
@@ -371,8 +371,8 @@ public abstract class AbstractBDIAgent extends Agent implements BDIAgent {
* @param goalListener
* the listener to be notified.
*/
- private final Intention addIntention(Capability dispatcher, Goal goal,
- GoalListener goalListener) throws IllegalAccessException {
+ private final Intention addIntention(Capability dispatcher, Goal goal, GoalListener goalListener)
+ throws IllegalAccessException {
Intention intention = null;
synchronized (allIntentions) {
intention = allIntentions.get(goal);
@@ -479,8 +479,7 @@ public abstract class AbstractBDIAgent extends Agent implements BDIAgent {
private final void fireGoalEvent(Intention intention) {
Goal goal = intention.getGoal();
GoalStatus status = intention.getStatus();
- log.debug("Goal: " + goal.getClass().getSimpleName() + " (" + status
- + ") - " + goal);
+ log.debug("Goal: " + goal.getClass().getSimpleName() + " (" + status + ") - " + goal);
GoalEvent goalEvent = new GoalEvent(goal, status);
synchronized (goalListeners) {
@@ -565,15 +564,12 @@ public abstract class AbstractBDIAgent extends Agent implements BDIAgent {
* @return the capability instances related to this capability that owns the
* goal, or an empty set if the agent cannot add this goal.
*/
- protected final Set<Capability> getGoalOwner(
- Class<? extends Capability> owner, boolean internal) {
+ protected final Set<Capability> getGoalOwner(Class<? extends Capability> owner, boolean internal) {
if (internal) {
return new HashSet<Capability>();
} else {
- Set<Capability> restrictedAccessOwners = restrictedAccessOwnersMap
- .get(owner);
- return restrictedAccessOwners == null ? new HashSet<Capability>()
- : restrictedAccessOwners;
+ Set<Capability> restrictedAccessOwners = restrictedAccessOwnersMap.get(owner);
+ return restrictedAccessOwners == null ? new HashSet<Capability>() : restrictedAccessOwners;
}
}
@@ -696,8 +692,7 @@ public abstract class AbstractBDIAgent extends Agent implements BDIAgent {
for (Capability capability : addedCapabilities) {
if (capability.getMyAgent() != null) {
throw new IllegalArgumentException(
- "Capability already binded to another agent: "
- + capability.getFullId());
+ "Capability already binded to another agent: " + capability.getFullId());
}
capability.setMyAgent(this);
}
@@ -718,8 +713,7 @@ public abstract class AbstractBDIAgent extends Agent implements BDIAgent {
* @param beliefRevisionStrategy
* the beliefRevisionStrategy to set.
*/
- public final void setBeliefRevisionStrategy(
- AgentBeliefRevisionStrategy beliefRevisionStrategy) {
+ public final void setBeliefRevisionStrategy(AgentBeliefRevisionStrategy beliefRevisionStrategy) {
if (beliefRevisionStrategy == null) {
this.beliefRevisionStrategy = new DefaultAgentBeliefRevisionStrategy();
} else {
@@ -735,8 +729,7 @@ public abstract class AbstractBDIAgent extends Agent implements BDIAgent {
* @param deliberationFunction
* the deliberationFunction to set.
*/
- public final void setDeliberationFunction(
- AgentDeliberationFunction deliberationFunction) {
+ public final void setDeliberationFunction(AgentDeliberationFunction deliberationFunction) {
if (deliberationFunction == null) {
this.deliberationFunction = new DefaultAgentDeliberationFunction();
} else {
@@ -752,8 +745,7 @@ public abstract class AbstractBDIAgent extends Agent implements BDIAgent {
* @param optionGenerationFunction
* the optionGenerationFunction to set.
*/
- public final void setOptionGenerationFunction(
- AgentOptionGenerationFunction optionGenerationFunction) {
+ public final void setOptionGenerationFunction(AgentOptionGenerationFunction optionGenerationFunction) {
if (optionGenerationFunction == null) {
this.optionGenerationFunction = new DefaultAgentOptionGenerationFunction();
} else {
@@ -769,8 +761,7 @@ public abstract class AbstractBDIAgent extends Agent implements BDIAgent {
* @param planSelectionStrategy
* the planSelectionStrategy to set.
*/
- public final void setPlanSelectionStrategy(
- AgentPlanSelectionStrategy planSelectionStrategy) {
+ public final void setPlanSelectionStrategy(AgentPlanSelectionStrategy planSelectionStrategy) {
if (planSelectionStrategy == null) {
this.planSelectionStrategy = new DefaultAgentPlanSelectionStrategy();
} else {
bdi-jade/src/bdi4jade/core/BDIAgent.java 36(+22 -14)
diff --git a/bdi-jade/src/bdi4jade/core/BDIAgent.java b/bdi-jade/src/bdi4jade/core/BDIAgent.java
index 82ceaba..917013c 100644
--- a/bdi-jade/src/bdi4jade/core/BDIAgent.java
+++ b/bdi-jade/src/bdi4jade/core/BDIAgent.java
@@ -22,17 +22,6 @@
package bdi4jade.core;
-import jade.content.ContentManager;
-import jade.core.AID;
-import jade.core.Agent;
-import jade.core.AgentState;
-import jade.core.Location;
-import jade.core.ServiceException;
-import jade.core.ServiceHelper;
-import jade.core.Timer;
-import jade.lang.acl.ACLMessage;
-import jade.lang.acl.MessageTemplate;
-
import java.util.Collection;
import java.util.List;
import java.util.Set;
@@ -45,6 +34,16 @@ import bdi4jade.reasoning.AgentBeliefRevisionStrategy;
import bdi4jade.reasoning.AgentDeliberationFunction;
import bdi4jade.reasoning.AgentOptionGenerationFunction;
import bdi4jade.reasoning.AgentPlanSelectionStrategy;
+import jade.content.ContentManager;
+import jade.core.AID;
+import jade.core.Agent;
+import jade.core.AgentState;
+import jade.core.Location;
+import jade.core.ServiceException;
+import jade.core.ServiceHelper;
+import jade.core.Timer;
+import jade.lang.acl.ACLMessage;
+import jade.lang.acl.MessageTemplate;
/**
* This interfaces represents a BDIAgent that has a current set of goals, which
@@ -81,8 +80,7 @@ public interface BDIAgent {
*
* @return true if the goal was added, false otherwise.
*/
- public boolean addGoal(Capability dispatcher, Goal goal,
- GoalListener goalListener);
+ public boolean addGoal(Capability dispatcher, Goal goal, GoalListener goalListener);
/**
* Adds a new goal to this agent to be achieved.
@@ -108,6 +106,16 @@ public interface BDIAgent {
public boolean addGoal(Goal goal, GoalListener goalListener);
/**
+ * Adds a listener to be notified when about events of a goal.
+ *
+ * @param goal
+ * the goal to be monitored.
+ * @param goalListener
+ * the listener to be notified.
+ */
+ public boolean addGoalListener(Goal goal, GoalListener goalListener);
+
+ /**
* Adds a listener to be notified when about goal events.
*
* @param goalListener
@@ -406,7 +414,7 @@ public interface BDIAgent {
* @see Agent#send(ACLMessage)
*/
public void send(ACLMessage msg);
-
+
/**
* @see Agent#setQueueSize(int)
*/
bdi-jade/src/bdi4jade/goal/NestedGoal.java 43(+43 -0)
diff --git a/bdi-jade/src/bdi4jade/goal/NestedGoal.java b/bdi-jade/src/bdi4jade/goal/NestedGoal.java
new file mode 100644
index 0000000..40d0ff5
--- /dev/null
+++ b/bdi-jade/src/bdi4jade/goal/NestedGoal.java
@@ -0,0 +1,43 @@
+//----------------------------------------------------------------------------
+// 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.goal;
+
+/**
+ * @author ingridnunes
+ *
+ */
+public class NestedGoal implements Goal {
+
+ private static final long serialVersionUID = -7779648429437829445L;
+
+ private final Goal goal;
+
+ public NestedGoal(Goal goal) {
+ this.goal = goal;
+ }
+
+ public Goal getGoal() {
+ return goal;
+ }
+
+}
diff --git a/bdi-jade/src/bdi4jade/plan/AbstractPlan.java b/bdi-jade/src/bdi4jade/plan/AbstractPlan.java
index 23d26fe..9e0de58 100644
--- a/bdi-jade/src/bdi4jade/plan/AbstractPlan.java
+++ b/bdi-jade/src/bdi4jade/plan/AbstractPlan.java
@@ -22,16 +22,16 @@
package bdi4jade.plan;
-import jade.lang.acl.ACLMessage;
-import jade.lang.acl.MessageTemplate;
-
import java.util.HashSet;
import java.util.Set;
import bdi4jade.core.MetadataElementImpl;
import bdi4jade.goal.Goal;
import bdi4jade.goal.GoalTemplate;
+import bdi4jade.goal.NestedGoal;
import bdi4jade.message.MessageGoal;
+import jade.lang.acl.ACLMessage;
+import jade.lang.acl.MessageTemplate;
/**
* This class represents the plan abstraction, being an abstract implementation
@@ -89,8 +89,7 @@ public abstract class AbstractPlan extends MetadataElementImpl implements Plan {
* @param messageTemplate
* the template of messages that this plan can process.
*/
- public AbstractPlan(String id, GoalTemplate goalTemplate,
- MessageTemplate messageTemplate) {
+ public AbstractPlan(String id, GoalTemplate goalTemplate, MessageTemplate messageTemplate) {
this();
if (id == null) {
throw new RuntimeException("Plan id cannot be null.");
@@ -162,7 +161,11 @@ public abstract class AbstractPlan extends MetadataElementImpl implements Plan {
canAchieve = canProcess(((MessageGoal) goal).getMessage());
} else {
for (GoalTemplate template : goalTemplates) {
- if (template.match(goal)) {
+ Goal realGoal = goal;
+ if (goal instanceof NestedGoal) {
+ realGoal = ((NestedGoal) goal).getGoal();
+ }
+ if (template.match(realGoal)) {
canAchieve = true;
break;
}
bdi-jade/src/bdi4jade/plan/DefaultPlan.java 68(+35 -33)
diff --git a/bdi-jade/src/bdi4jade/plan/DefaultPlan.java b/bdi-jade/src/bdi4jade/plan/DefaultPlan.java
index 1fc7ef2..ecfbde9 100644
--- a/bdi-jade/src/bdi4jade/plan/DefaultPlan.java
+++ b/bdi-jade/src/bdi4jade/plan/DefaultPlan.java
@@ -22,9 +22,6 @@
package bdi4jade.plan;
-import jade.core.behaviours.Behaviour;
-import jade.lang.acl.MessageTemplate;
-
import java.lang.reflect.Modifier;
import bdi4jade.core.BDIAgent;
@@ -34,6 +31,8 @@ import bdi4jade.goal.Goal;
import bdi4jade.goal.GoalTemplate;
import bdi4jade.goal.GoalTemplateFactory;
import bdi4jade.plan.planbody.PlanBody;
+import jade.core.behaviours.Behaviour;
+import jade.lang.acl.MessageTemplate;
/**
* This class represents a plan whose plan body is a class that can be
@@ -45,9 +44,8 @@ import bdi4jade.plan.planbody.PlanBody;
*/
public class DefaultPlan extends AbstractPlan {
- private static String generateId(Class<? extends Goal> goalClass,
- GoalTemplate goalTemplate, MessageTemplate messageTemplate,
- Class<? extends PlanBody> planBodyClass) {
+ private static String generateId(Class<? extends Goal> goalClass, GoalTemplate goalTemplate,
+ MessageTemplate messageTemplate, Class<? extends PlanBody> planBodyClass) {
StringBuffer sb = new StringBuffer("[");
if (goalClass != null) {
sb.append(" ").append(goalClass.getName());
@@ -75,10 +73,8 @@ public class DefaultPlan extends AbstractPlan {
* @param planBodyClass
* the class of this plan body.
*/
- public DefaultPlan(Class<? extends Goal> goalClass,
- Class<? extends PlanBody> planBodyClass) {
- super(generateId(goalClass, null, null, planBodyClass),
- GoalTemplateFactory.goalOfType(goalClass));
+ public DefaultPlan(Class<? extends Goal> goalClass, Class<? extends PlanBody> planBodyClass) {
+ super(generateId(goalClass, null, null, planBodyClass), GoalTemplateFactory.goalOfType(goalClass));
this.planBodyClass = planBodyClass;
}
@@ -108,8 +104,7 @@ public class DefaultPlan extends AbstractPlan {
* @param planBodyClass
* the class of this plan body.
*/
- public DefaultPlan(GoalTemplate goalTemplate,
- Class<? extends PlanBody> planBodyClass) {
+ public DefaultPlan(GoalTemplate goalTemplate, Class<? extends PlanBody> planBodyClass) {
super(generateId(null, goalTemplate, null, planBodyClass), goalTemplate);
this.planBodyClass = planBodyClass;
}
@@ -134,11 +129,27 @@ public class DefaultPlan extends AbstractPlan {
* @param planBodyClass
* the class of this plan body.
*/
- public DefaultPlan(GoalTemplate goalTemplate,
- MessageTemplate messageTemplate,
+ public DefaultPlan(GoalTemplate goalTemplate, MessageTemplate messageTemplate,
Class<? extends PlanBody> planBodyClass) {
- super(generateId(null, goalTemplate, messageTemplate, planBodyClass),
- goalTemplate, messageTemplate);
+ super(generateId(null, goalTemplate, messageTemplate, planBodyClass), goalTemplate, messageTemplate);
+ this.planBodyClass = planBodyClass;
+ }
+
+ /**
+ * Creates a new simple plan, which is able to achieve goals that match the
+ * provided templates. It is a plan whose body is the specified class and
+ * its id is the plan body class name.
+ *
+ * @param goalTemplate
+ * the template of goals that this plan can achieve.
+ * @param planBodyClass
+ * the class of this plan body.
+ */
+ public DefaultPlan(GoalTemplate[] goalTemplates, Class<? extends PlanBody> planBodyClass) {
+ super(generateId(null, goalTemplates[0], null, planBodyClass));
+ for (GoalTemplate goalTemplate : goalTemplates) {
+ addGoalTemplate(goalTemplate);
+ }
this.planBodyClass = planBodyClass;
}
@@ -156,10 +167,8 @@ public class DefaultPlan extends AbstractPlan {
* @param planBodyClass
* the class of this plan body.
*/
- public DefaultPlan(MessageTemplate messageTemplate,
- Class<? extends PlanBody> planBodyClass) {
- super(generateId(null, null, messageTemplate, planBodyClass),
- messageTemplate);
+ public DefaultPlan(MessageTemplate messageTemplate, Class<? extends PlanBody> planBodyClass) {
+ super(generateId(null, null, messageTemplate, planBodyClass), messageTemplate);
this.planBodyClass = planBodyClass;
}
@@ -197,8 +206,7 @@ public class DefaultPlan extends AbstractPlan {
* @param planBodyClass
* the class of this plan body.
*/
- public DefaultPlan(String id, GoalTemplate goalTemplate,
- Class<? extends PlanBody> planBodyClass) {
+ public DefaultPlan(String id, GoalTemplate goalTemplate, Class<? extends PlanBody> planBodyClass) {
super(id, goalTemplate);
this.planBodyClass = planBodyClass;
}
@@ -224,8 +232,7 @@ public class DefaultPlan extends AbstractPlan {
* @param planBodyClass
* the class of this plan body.
*/
- public DefaultPlan(String id, GoalTemplate goalTemplate,
- MessageTemplate messageTemplate,
+ public DefaultPlan(String id, GoalTemplate goalTemplate, MessageTemplate messageTemplate,
Class<? extends PlanBody> planBodyClass) {
super(id, goalTemplate, messageTemplate);
this.planBodyClass = planBodyClass;
@@ -246,8 +253,7 @@ public class DefaultPlan extends AbstractPlan {
* @param planBodyClass
* the class of this plan body.
*/
- public DefaultPlan(String id, MessageTemplate messageTemplate,
- Class<? extends PlanBody> planBodyClass) {
+ public DefaultPlan(String id, MessageTemplate messageTemplate, Class<? extends PlanBody> planBodyClass) {
super(id, messageTemplate);
this.planBodyClass = planBodyClass;
}
@@ -262,20 +268,16 @@ public class DefaultPlan extends AbstractPlan {
public PlanBody createPlanBody() throws PlanInstantiationException {
try {
Class<?> enclosingClass = planBodyClass.getEnclosingClass();
- if (!Modifier.isStatic(planBodyClass.getModifiers())
- && enclosingClass != null) {
+ if (!Modifier.isStatic(planBodyClass.getModifiers()) && enclosingClass != null) {
if (BDIAgent.class.isAssignableFrom(enclosingClass)) {
return planBodyClass.getDeclaredConstructor(enclosingClass)
- .newInstance(
- getPlanLibrary().getCapability()
- .getMyAgent());
+ .newInstance(getPlanLibrary().getCapability().getMyAgent());
} else if (Capability.class.isAssignableFrom(enclosingClass)) {
return planBodyClass.getDeclaredConstructor(enclosingClass)
.newInstance(getPlanLibrary().getCapability());
} else {
assert Plan.class.isAssignableFrom(enclosingClass);
- return planBodyClass.getDeclaredConstructor(enclosingClass)
- .newInstance(this);
+ return planBodyClass.getDeclaredConstructor(enclosingClass).newInstance(this);
}
} else {
return this.planBodyClass.newInstance();
diff --git a/bdi-jade/src/bdi4jade/plan/planbody/AbstractPlanBody.java b/bdi-jade/src/bdi4jade/plan/planbody/AbstractPlanBody.java
index 1f87c7b..ef22ed6 100644
--- a/bdi-jade/src/bdi4jade/plan/planbody/AbstractPlanBody.java
+++ b/bdi-jade/src/bdi4jade/plan/planbody/AbstractPlanBody.java
@@ -22,8 +22,6 @@
package bdi4jade.plan.planbody;
-import jade.core.behaviours.Behaviour;
-
import java.util.ArrayList;
import java.util.Iterator;
import java.util.LinkedList;
@@ -40,9 +38,11 @@ import bdi4jade.event.GoalListener;
import bdi4jade.exception.ParameterException;
import bdi4jade.exception.PlanInstantiationException;
import bdi4jade.goal.Goal;
+import bdi4jade.goal.NestedGoal;
import bdi4jade.plan.Plan;
import bdi4jade.plan.Plan.EndState;
import bdi4jade.util.ReflectionUtils;
+import jade.core.behaviours.Behaviour;
/**
* This class provides an almost complete implementation of the {@link PlanBody}
@@ -76,16 +76,14 @@ public abstract class AbstractPlanBody extends Behaviour implements PlanBody {
* @see PlanBody#dispatchGoal(Goal)
*/
public boolean dispatchGoal(Goal goal) {
- return this.intention.getMyAgent().addGoal(
- this.plan.getPlanLibrary().getCapability(), goal);
+ return this.intention.getMyAgent().addGoal(this.plan.getPlanLibrary().getCapability(), goal);
}
/**
* @see PlanBody#dispatchSubgoal(Goal)
*/
public boolean dispatchSubgoal(Goal subgoal) {
- boolean goalAdded = this.intention.getMyAgent().addGoal(
- this.plan.getPlanLibrary().getCapability(), subgoal);
+ boolean goalAdded = this.intention.getMyAgent().addGoal(this.plan.getPlanLibrary().getCapability(), subgoal);
synchronized (subgoals) {
if (goalAdded)
this.subgoals.add(subgoal);
@@ -97,8 +95,8 @@ public abstract class AbstractPlanBody extends Behaviour implements PlanBody {
* @see PlanBody#dispatchSubgoalAndListen(Goal)
*/
public boolean dispatchSubgoalAndListen(Goal subgoal) {
- boolean goalAdded = this.intention.getMyAgent().addGoal(
- this.plan.getPlanLibrary().getCapability(), subgoal, this);
+ boolean goalAdded = this.intention.getMyAgent().addGoal(this.plan.getPlanLibrary().getCapability(), subgoal,
+ this);
synchronized (subgoals) {
if (goalAdded)
this.subgoals.add(subgoal);
@@ -168,7 +166,11 @@ public abstract class AbstractPlanBody extends Behaviour implements PlanBody {
* @return the goal.
*/
public final Goal getGoal() {
- return this.intention.getGoal();
+ if (this.intention.getGoal() instanceof NestedGoal) {
+ return ((NestedGoal) this.intention.getGoal()).getGoal();
+ } else {
+ return this.intention.getGoal();
+ }
}
/**
@@ -291,16 +293,14 @@ public abstract class AbstractPlanBody extends Behaviour implements PlanBody {
* @throws PlanInstantiationException
* if this plan body has already been initialized.
*/
- public final void init(Plan plan, Intention intention)
- throws PlanInstantiationException {
+ public final void init(Plan plan, Intention intention) throws PlanInstantiationException {
if (this.plan != null || this.intention != null) {
- throw new PlanInstantiationException(
- "This plan body has already been initialized.");
+ throw new PlanInstantiationException("This plan body has already been initialized.");
}
this.plan = plan;
this.intention = intention;
try {
- ReflectionUtils.setPlanBodyInput(this, intention.getGoal());
+ ReflectionUtils.setPlanBodyInput(this, getGoal());
ReflectionUtils.setupBeliefs(this);
} catch (ParameterException exc) {
throw new PlanInstantiationException(exc);
@@ -332,8 +332,7 @@ public abstract class AbstractPlanBody extends Behaviour implements PlanBody {
((OutputPlanBody) this).setGoalOutput(getGoal());
} else {
try {
- ReflectionUtils.setPlanBodyOutput(this,
- intention.getGoal());
+ ReflectionUtils.setPlanBodyOutput(this, getGoal());
} catch (ParameterException exc) {
log.warn("Could not set all goal outputs: " + exc);
}
bdi-jade-extensions/.classpath 2(+1 -1)
diff --git a/bdi-jade-extensions/.classpath b/bdi-jade-extensions/.classpath
index bdac129..42c9295 100644
--- a/bdi-jade-extensions/.classpath
+++ b/bdi-jade-extensions/.classpath
@@ -2,10 +2,10 @@
<classpath>
<classpathentry kind="src" path="src"/>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
- <classpathentry combineaccessrules="false" kind="src" path="/bdi-jade"/>
<classpathentry kind="lib" path="/bdi-jade/lib/commons-logging-1.1.3.jar"/>
<classpathentry kind="lib" path="/bdi-jade/lib/jade-4.3.2.jar"/>
<classpathentry kind="lib" path="/bdi-jade/lib/log4j-1.2.17.jar"/>
<classpathentry kind="lib" path="lib/weka.jar"/>
+ <classpathentry combineaccessrules="false" kind="src" path="/bdi-jade"/>
<classpathentry kind="output" path="bin"/>
</classpath>
diff --git a/bdi-jade-extensions/src/bdi4jade/extension/palliative/goal/CauseEffectProblem.java b/bdi-jade-extensions/src/bdi4jade/extension/palliative/goal/CauseEffectProblem.java
new file mode 100644
index 0000000..2a76d95
--- /dev/null
+++ b/bdi-jade-extensions/src/bdi4jade/extension/palliative/goal/CauseEffectProblem.java
@@ -0,0 +1,107 @@
+package bdi4jade.extension.palliative.goal;
+
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Set;
+
+import bdi4jade.core.BDIAgent;
+import bdi4jade.event.GoalEvent;
+import bdi4jade.event.GoalListener;
+import bdi4jade.extension.palliative.graph.CauseEffectRelationship;
+import bdi4jade.extension.palliative.logics.Fact;
+import bdi4jade.goal.BeliefValueGoal;
+import bdi4jade.goal.Goal;
+import bdi4jade.goal.GoalStatus;
+
+public class CauseEffectProblem implements GoalListener {
+
+ public enum CauseEffectProblemStatus {
+ CAUSE_PARTIALLY_RESOLVED, CAUSE_RESOLVED, FULLY_RESOLVED, MITIGATED, PARTIALLY_RESOLVED, UNSUCCESSFUL;
+ }
+
+ private final CauseEffectRelationship causeEffectRelationship;
+ private Map<Fact, CauseFactorStatus> causeFactorStatus;
+ private final BeliefValueGoal<?, ?> effectGoal;
+ private final Goal parentGoal;
+ private GoalStatus effectGoalStatus;
+ private CauseEffectProblemStatus status;
+
+ public CauseEffectProblem(BeliefValueGoal<?, ?> effectGoal, CauseEffectRelationship causeEffectRelationship,
+ BDIAgent agent, Goal parentGoal) {
+ this.effectGoal = effectGoal;
+ this.parentGoal = parentGoal;
+ this.causeEffectRelationship = causeEffectRelationship;
+ if (parentGoal != null) {
+ agent.addGoalListener(parentGoal, this);
+ } else {
+ agent.addGoalListener(effectGoal, this);
+ }
+
+ this.causeFactorStatus = new HashMap<>();
+ for (Fact fact : causeEffectRelationship.getAllPossibleCauses()) {
+ causeFactorStatus.put(fact, new CauseFactorStatus(fact));
+ }
+
+ this.effectGoalStatus = null;
+ this.status = null;
+ }
+
+ public void setCauseFactorStatus(Set<CauseFactorStatus> cause) {
+ this.causeFactorStatus = new HashMap<>();
+ for (CauseFactorStatus cf : cause) {
+ this.causeFactorStatus.put(cf.getFact(), cf);
+ }
+ }
+
+ public Collection<CauseFactorStatus> getCauseFactorStatus() {
+ return causeFactorStatus.values();
+ }
+
+ public CauseFactorStatus getCauseFactorStatus(Fact fact) {
+ return causeFactorStatus.get(fact);
+ }
+
+ public Goal getEffectGoal() {
+ return effectGoal;
+ }
+
+ public GoalStatus getEffectGoalStatus() {
+ return effectGoalStatus;
+ }
+
+ public CauseEffectProblemStatus getStatus() {
+ return status;
+ }
+
+ @Override
+ public void goalPerformed(GoalEvent event) {
+ if ((event.getGoal() == effectGoal || event.getGoal() == parentGoal) && event.getStatus().isFinished()) {
+ setEffectGoalStatus(event.getStatus());
+ }
+ }
+
+ public void setEffectGoalStatus(GoalStatus effectGoalStatus) {
+ this.effectGoalStatus = effectGoalStatus;
+ }
+
+ public void setStatus(CauseEffectProblemStatus status) {
+ this.status = status;
+ }
+
+ public CauseEffectRelationship getCauseEffectRelationship() {
+ return causeEffectRelationship;
+ }
+
+ @Override
+ public String toString() {
+ StringBuffer sb = new StringBuffer();
+ sb.append("< ").append(effectGoal).append(" [").append(effectGoalStatus).append("], {\n");
+ for (CauseFactorStatus cf : causeFactorStatus.values()) {
+ sb.append("\t").append(cf).append("\n");
+ }
+ sb.append("} > = ").append(status);
+ return sb.toString();
+ }
+
+}
diff --git a/bdi-jade-extensions/src/bdi4jade/extension/palliative/goal/CauseFactorStatus.java b/bdi-jade-extensions/src/bdi4jade/extension/palliative/goal/CauseFactorStatus.java
new file mode 100644
index 0000000..1ae135a
--- /dev/null
+++ b/bdi-jade-extensions/src/bdi4jade/extension/palliative/goal/CauseFactorStatus.java
@@ -0,0 +1,104 @@
+package bdi4jade.extension.palliative.goal;
+
+import bdi4jade.extension.palliative.logics.Fact;
+import bdi4jade.goal.BeliefPresentGoal;
+import bdi4jade.goal.Goal;
+import bdi4jade.goal.GoalStatus;
+import bdi4jade.goal.PredicateGoal;
+
+public class CauseFactorStatus {
+
+ private Goal achievementGoal;
+ private GoalStatus achievementGoalStatus;
+ private final Fact fact;
+ private Boolean initialStatus;
+ private Goal testGoal;
+ private GoalStatus testGoalStatus;
+ private Boolean updatedStatus;
+
+ public CauseFactorStatus(Fact fact) {
+ this.fact = fact;
+ this.initialStatus = null;
+ this.updatedStatus = null;
+ this.testGoal = null;
+ this.achievementGoal = null;
+ this.testGoalStatus = null;
+ this.achievementGoalStatus = null;
+ }
+
+ public PredicateGoal<?> generateAchievementGoal() {
+ this.achievementGoal = new PredicateGoal(this.fact.getPredicate(), !this.fact.getValue());
+ return (PredicateGoal<?>) this.achievementGoal;
+ }
+
+ public BeliefPresentGoal<?> generateTestGoal() {
+ this.testGoal = new BeliefPresentGoal<Object>(this.fact.getPredicate());
+ return (BeliefPresentGoal<?>) this.testGoal;
+ }
+
+ public Goal getAchievementGoal() {
+ return achievementGoal;
+ }
+
+ public GoalStatus getAchievementGoalStatus() {
+ return achievementGoalStatus;
+ }
+
+ public Fact getFact() {
+ return fact;
+ }
+
+ public Boolean getInitialStatus() {
+ return initialStatus;
+ }
+
+ public Goal getTestGoal() {
+ return testGoal;
+ }
+
+ public GoalStatus getTestGoalStatus() {
+ return testGoalStatus;
+ }
+
+ public Boolean getUpdatedStatus() {
+ return updatedStatus;
+ }
+
+ public void setAchievementGoal(Goal achievementGoal) {
+ this.achievementGoal = achievementGoal;
+ }
+
+ public void setAchievementGoalStatus(GoalStatus achievementGoalStatus) {
+ this.achievementGoalStatus = achievementGoalStatus;
+ }
+
+ public void setInitialStatus(Boolean initialStatus) {
+ this.initialStatus = initialStatus;
+ }
+
+ public void setTestGoal(Goal testGoal) {
+ this.testGoal = testGoal;
+ }
+
+ public void setTestGoalStatus(GoalStatus testGoalStatus) {
+ this.testGoalStatus = testGoalStatus;
+ }
+
+ public void setUpdatedStatus(Boolean updatedStatus) {
+ this.updatedStatus = updatedStatus;
+ }
+
+ @Override
+ public String toString() {
+ StringBuffer sb = new StringBuffer();
+ sb.append("< ").append(fact);
+ sb.append(", s_i = ").append(initialStatus);
+ sb.append(", s_u = ").append(updatedStatus);
+ sb.append(", ?g = ").append(testGoal);
+ sb.append(" [").append(testGoalStatus).append("]");
+ sb.append(", !g = ").append(achievementGoal);
+ sb.append(" [").append(achievementGoalStatus).append("] >");
+ return sb.toString();
+ }
+
+}
diff --git a/bdi-jade-extensions/src/bdi4jade/extension/palliative/goal/ConstrainedGoal.java b/bdi-jade-extensions/src/bdi4jade/extension/palliative/goal/ConstrainedGoal.java
new file mode 100644
index 0000000..1a15b30
--- /dev/null
+++ b/bdi-jade-extensions/src/bdi4jade/extension/palliative/goal/ConstrainedGoal.java
@@ -0,0 +1,54 @@
+package bdi4jade.extension.palliative.goal;
+
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+import bdi4jade.extension.palliative.Resource;
+import bdi4jade.extension.palliative.logics.LogicalExpression;
+import bdi4jade.goal.Goal;
+import bdi4jade.goal.NestedGoal;
+
+public class ConstrainedGoal extends NestedGoal {
+
+ private static final long serialVersionUID = -7779648429437829445L;
+
+ private Map<Resource, ObjectiveFunction> objectiveFunction;
+ private Set<LogicalExpression> operationConstraints;
+
+ public ConstrainedGoal(Goal goal) {
+ super(goal);
+ this.operationConstraints = new HashSet<>();
+ this.objectiveFunction = new HashMap<>();
+ }
+
+ public void addObjectiveFunction(Resource resource, ObjectiveFunction objectiveFunction) {
+ this.objectiveFunction.put(resource, objectiveFunction);
+ }
+
+ public void addOperationConstraint(LogicalExpression constraint) {
+ this.operationConstraints.add(constraint);
+ }
+
+ public Map<Resource, ObjectiveFunction> getObjectiveFunction() {
+ return objectiveFunction;
+ }
+
+ public ObjectiveFunction getObjectiveFunction(Resource resource) {
+ return this.objectiveFunction.get(resource);
+ }
+
+ public Set<LogicalExpression> getOperationConstraints() {
+ return operationConstraints;
+ }
+
+ public void setObjectiveFunction(Map<Resource, ObjectiveFunction> objectiveFunction) {
+ this.objectiveFunction = objectiveFunction;
+ }
+
+ public void setOperationConstraints(Set<LogicalExpression> operationConstraints) {
+ this.operationConstraints = operationConstraints;
+ }
+
+}
diff --git a/bdi-jade-extensions/src/bdi4jade/extension/palliative/goal/ObjectiveFunction.java b/bdi-jade-extensions/src/bdi4jade/extension/palliative/goal/ObjectiveFunction.java
new file mode 100644
index 0000000..0272fd4
--- /dev/null
+++ b/bdi-jade-extensions/src/bdi4jade/extension/palliative/goal/ObjectiveFunction.java
@@ -0,0 +1,7 @@
+package bdi4jade.extension.palliative.goal;
+
+public enum ObjectiveFunction {
+
+ MAXIMIZE, MINIMIZE;
+
+}
diff --git a/bdi-jade-extensions/src/bdi4jade/extension/palliative/graph/AlternativeCauseSet.java b/bdi-jade-extensions/src/bdi4jade/extension/palliative/graph/AlternativeCauseSet.java
new file mode 100644
index 0000000..6fa3870
--- /dev/null
+++ b/bdi-jade-extensions/src/bdi4jade/extension/palliative/graph/AlternativeCauseSet.java
@@ -0,0 +1,44 @@
+package bdi4jade.extension.palliative.graph;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import bdi4jade.extension.palliative.logics.Fact;
+
+public class AlternativeCauseSet {
+
+ private List<Fact> alternativeCauses;
+ private Integer max;
+ private Integer min;
+
+ public AlternativeCauseSet(Integer min, Integer max) {
+ setMin(min);
+ setMax(max);
+ this.alternativeCauses = new ArrayList<>();
+ }
+
+ public void addAlternativeCause(Fact cause) {
+ this.alternativeCauses.add(cause);
+ }
+
+ public List<Fact> getAlternativeCauses() {
+ return this.alternativeCauses;
+ }
+
+ public Integer getMax() {
+ return this.max;
+ }
+
+ public Integer getMin() {
+ return this.min;
+ }
+
+ public void setMax(Integer max) {
+ this.max = max;
+ }
+
+ public void setMin(Integer min) {
+ this.min = min;
+ }
+
+}
diff --git a/bdi-jade-extensions/src/bdi4jade/extension/palliative/graph/CauseEffectKnowledgeModel.java b/bdi-jade-extensions/src/bdi4jade/extension/palliative/graph/CauseEffectKnowledgeModel.java
new file mode 100644
index 0000000..37c81db
--- /dev/null
+++ b/bdi-jade-extensions/src/bdi4jade/extension/palliative/graph/CauseEffectKnowledgeModel.java
@@ -0,0 +1,42 @@
+package bdi4jade.extension.palliative.graph;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import bdi4jade.belief.TransientBelief;
+import bdi4jade.extension.palliative.logics.Fact;
+import bdi4jade.extension.palliative.logics.Predicate;
+import bdi4jade.goal.BeliefValueGoal;
+import bdi4jade.goal.Goal;
+import bdi4jade.goal.PredicateGoal;
+
+public class CauseEffectKnowledgeModel extends TransientBelief<String, Map<Fact, CauseEffectRelationship>> {
+
+ public static final String NAME = "CauseEffectModel";
+
+ public CauseEffectKnowledgeModel() {
+ super(NAME, new HashMap<>());
+ }
+
+ public void addCauseEffectRelationship(CauseEffectRelationship causes) {
+ this.getValue().put(causes.getEffect(), causes);
+ }
+
+ public CauseEffectRelationship getCauseEffectRelationship(Goal goal) {
+ if (goal instanceof PredicateGoal<?>) {
+ PredicateGoal<? extends Predicate> bgoal = (PredicateGoal<? extends Predicate>) goal;
+ Fact fact = new Fact(bgoal.getBeliefName(), !bgoal.getValue());
+ return getCausesOf(fact);
+ }
+ return null;
+ }
+
+ public CauseEffectRelationship getCausesOf(Fact effect) {
+ return this.getValue().get(effect);
+ }
+
+ public boolean isEffect(Fact fact) {
+ return getValue().containsKey(fact);
+ }
+
+}
diff --git a/bdi-jade-extensions/src/bdi4jade/extension/palliative/graph/CauseEffectRelationship.java b/bdi-jade-extensions/src/bdi4jade/extension/palliative/graph/CauseEffectRelationship.java
new file mode 100644
index 0000000..48bbb7f
--- /dev/null
+++ b/bdi-jade-extensions/src/bdi4jade/extension/palliative/graph/CauseEffectRelationship.java
@@ -0,0 +1,65 @@
+package bdi4jade.extension.palliative.graph;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import bdi4jade.extension.palliative.logics.Fact;
+
+public class CauseEffectRelationship {
+
+ private List<AlternativeCauseSet> alternativeCauseSets;
+ private Fact effect;
+ private List<Fact> mandatoryCauses;
+ private List<Fact> optionalCauses;
+
+ public CauseEffectRelationship(Fact effect) {
+ this.effect = effect;
+ this.mandatoryCauses = new ArrayList<>();
+ this.optionalCauses = new ArrayList<>();
+ this.alternativeCauseSets = new ArrayList<>();
+ }
+
+ public void addAlternativeCauseSet(AlternativeCauseSet acs) {
+ this.alternativeCauseSets.add(acs);
+ }
+
+ public void addMandatoryCause(Fact cause) {
+ this.mandatoryCauses.add(cause);
+ }
+
+ public void addOptionalCause(Fact cause) {
+ this.optionalCauses.add(cause);
+ }
+
+ public List<Fact> getAllPossibleCauses() {
+ ArrayList<Fact> possibleCauses = new ArrayList<>();
+ possibleCauses.addAll(mandatoryCauses);
+ possibleCauses.addAll(optionalCauses);
+ possibleCauses.addAll(getAlternativeCauses());
+ return possibleCauses;
+ }
+
+ public List<Fact> getAlternativeCauses() {
+ ArrayList<Fact> alternativeCauses = new ArrayList<>();
+ for (AlternativeCauseSet causeSet : this.alternativeCauseSets) {
+ alternativeCauses.addAll(causeSet.getAlternativeCauses());
+ }
+ return alternativeCauses;
+ }
+
+ public List<AlternativeCauseSet> getAlternativeCauseSets() {
+ return this.alternativeCauseSets;
+ }
+
+ public Fact getEffect() {
+ return effect;
+ }
+
+ public List<Fact> getMandatoryCauses() {
+ return this.mandatoryCauses;
+ }
+
+ public List<Fact> getOptionalCauses() {
+ return this.optionalCauses;
+ }
+}
diff --git a/bdi-jade-extensions/src/bdi4jade/extension/palliative/logics/And.java b/bdi-jade-extensions/src/bdi4jade/extension/palliative/logics/And.java
new file mode 100644
index 0000000..7642eb0
--- /dev/null
+++ b/bdi-jade-extensions/src/bdi4jade/extension/palliative/logics/And.java
@@ -0,0 +1,65 @@
+//----------------------------------------------------------------------------
+// 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.extension.palliative.logics;
+
+import java.util.Map;
+
+import bdi4jade.belief.BeliefBase;
+
+/**
+ * @author ingridnunes
+ *
+ */
+public class And extends BinaryLogicalExpression {
+
+ public And() {
+
+ }
+
+ public And(LogicalExpression expression1, LogicalExpression expression2) {
+ super(expression1, expression2);
+ }
+
+ @Override
+ public Boolean getValue(BeliefBase beliefBase) {
+ return getExpression1().getValue(beliefBase) && getExpression2().getValue(beliefBase);
+ }
+
+ @Override
+ public Boolean getValue(Map<Object, Object> values) {
+ return getExpression1().getValue(values) && getExpression2().getValue(values);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see java.lang.Object#toString()
+ */
+ @Override
+ public String toString() {
+ StringBuffer sb = new StringBuffer();
+ sb.append("(").append(expression1).append(" ^ ").append(expression2).append(")");
+ return sb.toString();
+ }
+
+}
diff --git a/bdi-jade-extensions/src/bdi4jade/extension/palliative/logics/BinaryLogicalExpression.java b/bdi-jade-extensions/src/bdi4jade/extension/palliative/logics/BinaryLogicalExpression.java
new file mode 100644
index 0000000..6aa2344
--- /dev/null
+++ b/bdi-jade-extensions/src/bdi4jade/extension/palliative/logics/BinaryLogicalExpression.java
@@ -0,0 +1,73 @@
+//----------------------------------------------------------------------------
+// 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.extension.palliative.logics;
+
+/**
+ * @author ingridnunes
+ *
+ */
+public abstract class BinaryLogicalExpression implements LogicalExpression {
+
+ protected LogicalExpression expression1;
+ protected LogicalExpression expression2;
+
+ public BinaryLogicalExpression() {
+
+ }
+
+ public BinaryLogicalExpression(LogicalExpression expression1, LogicalExpression expression2) {
+ this.expression1 = expression1;
+ this.expression2 = expression2;
+ }
+
+ /**
+ * @return the expression1
+ */
+ public LogicalExpression getExpression1() {
+ return expression1;
+ }
+
+ /**
+ * @return the expression2
+ */
+ public LogicalExpression getExpression2() {
+ return expression2;
+ }
+
+ /**
+ * @param expression1
+ * the expression1 to set
+ */
+ public void setExpression1(LogicalExpression expression1) {
+ this.expression1 = expression1;
+ }
+
+ /**
+ * @param expression2
+ * the expression2 to set
+ */
+ public void setExpression2(LogicalExpression expression2) {
+ this.expression2 = expression2;
+ }
+
+}
diff --git a/bdi-jade-extensions/src/bdi4jade/extension/palliative/logics/BinaryPredicate.java b/bdi-jade-extensions/src/bdi4jade/extension/palliative/logics/BinaryPredicate.java
new file mode 100644
index 0000000..28167c9
--- /dev/null
+++ b/bdi-jade-extensions/src/bdi4jade/extension/palliative/logics/BinaryPredicate.java
@@ -0,0 +1,94 @@
+//----------------------------------------------------------------------------
+// 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.extension.palliative.logics;
+
+/**
+ * @author Ingrid Nunes
+ */
+public abstract class BinaryPredicate<T, U> extends Predicate {
+
+ private static final long serialVersionUID = -1506723105103606268L;
+
+ protected T variable1;
+ protected U variable2;
+
+ public BinaryPredicate() {
+
+ }
+
+ public BinaryPredicate(T first, U second) {
+ this.variable1 = first;
+ this.variable2 = second;
+ }
+
+ protected void appendVariables(StringBuffer sb) {
+ sb.append(variable1);
+ sb.append(",");
+ sb.append(variable2);
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (obj != null && this.getClass().equals(obj.getClass())) {
+ BinaryPredicate<?, ?> p = (BinaryPredicate<?, ?>) obj;
+ return this.variable1.equals(p.variable1) && this.variable2.equals(p.variable2);
+ }
+ return false;
+ }
+
+ public T getVariable1() {
+ return variable1;
+ }
+
+ public U getVariable2() {
+ return variable2;
+ }
+
+ @Override
+ public int hashCode() {
+ final int prime = 31;
+ int result = 1;
+ result = prime * result + ((this.getClass() == null) ? 0 : this.getClass().hashCode());
+ result = prime * result + ((variable1 == null) ? 0 : variable1.hashCode());
+ result = prime * result + ((variable2 == null) ? 0 : variable2.hashCode());
+ return result;
+ }
+
+ public void setVariable1(T first) {
+ this.variable1 = first;
+ }
+
+ public void setVariable2(U second) {
+ this.variable2 = second;
+ }
+
+ @Override
+ public String toString() {
+ StringBuffer sb = new StringBuffer();
+ sb.append(super.toString());
+ sb.append("(");
+ appendVariables(sb);
+ sb.append(")");
+ return sb.toString();
+ }
+
+}
diff --git a/bdi-jade-extensions/src/bdi4jade/extension/palliative/logics/Fact.java b/bdi-jade-extensions/src/bdi4jade/extension/palliative/logics/Fact.java
new file mode 100644
index 0000000..a0cb052
--- /dev/null
+++ b/bdi-jade-extensions/src/bdi4jade/extension/palliative/logics/Fact.java
@@ -0,0 +1,57 @@
+package bdi4jade.extension.palliative.logics;
+
+import java.io.Serializable;
+
+import jade.content.Concept;
+import jade.content.ContentElement;
+
+public class Fact implements Serializable, Concept, ContentElement {
+
+ private static final long serialVersionUID = -7208284763130171013L;
+
+ private Predicate proposition;
+ private Boolean value;
+
+ public Fact(Predicate proposition, Boolean val) {
+ this.proposition = proposition;
+ this.value = val;
+ }
+
+ public Predicate getPredicate() {
+ return proposition;
+ }
+
+ public Boolean getValue() {
+ return this.value;
+ }
+
+ @Override
+ public String toString() {
+ StringBuffer sb = new StringBuffer();
+ if (value == null) {
+ sb.append("not ");
+ } else if (!value) {
+ sb.append("~");
+ }
+ sb.append(proposition);
+ return sb.toString();
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (!(obj instanceof Fact))
+ return false;
+ Fact other = (Fact) obj;
+ return this.proposition.equals(other.proposition) && this.value.equals(other.value);
+ }
+
+ @Override
+ public int hashCode() {
+ final int prime = 31;
+ int result = 1;
+ result = prime * result + proposition.hashCode();
+ result = prime * result + value.hashCode();
+ return result;
+ }
+
+}
diff --git a/bdi-jade-extensions/src/bdi4jade/extension/palliative/logics/Implication.java b/bdi-jade-extensions/src/bdi4jade/extension/palliative/logics/Implication.java
new file mode 100644
index 0000000..adbcaac
--- /dev/null
+++ b/bdi-jade-extensions/src/bdi4jade/extension/palliative/logics/Implication.java
@@ -0,0 +1,65 @@
+//----------------------------------------------------------------------------
+// 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.extension.palliative.logics;
+
+import java.util.Map;
+
+import bdi4jade.belief.BeliefBase;
+
+/**
+ * @author ingridnunes
+ *
+ */
+public class Implication extends BinaryLogicalExpression {
+
+ public Implication() {
+
+ }
+
+ public Implication(LogicalExpression expression1, LogicalExpression expression2) {
+ super(expression1, expression2);
+ }
+
+ @Override
+ public Boolean getValue(BeliefBase beliefBase) {
+ return !getExpression1().getValue(beliefBase) || getExpression2().getValue(beliefBase);
+ }
+
+ @Override
+ public Boolean getValue(Map<Object, Object> values) {
+ return !getExpression1().getValue(values) || getExpression2().getValue(values);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see java.lang.Object#toString()
+ */
+ @Override
+ public String toString() {
+ StringBuffer sb = new StringBuffer();
+ sb.append("(").append(expression1).append(" -> ").append(expression2).append(")");
+ return sb.toString();
+ }
+
+}
diff --git a/bdi-jade-extensions/src/bdi4jade/extension/palliative/logics/LogicalExpression.java b/bdi-jade-extensions/src/bdi4jade/extension/palliative/logics/LogicalExpression.java
new file mode 100644
index 0000000..a5032d5
--- /dev/null
+++ b/bdi-jade-extensions/src/bdi4jade/extension/palliative/logics/LogicalExpression.java
@@ -0,0 +1,42 @@
+//----------------------------------------------------------------------------
+// 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.extension.palliative.logics;
+
+import java.io.Serializable;
+import java.util.Map;
+
+import bdi4jade.belief.BeliefBase;
+import jade.content.Concept;
+import jade.content.ContentElement;
+
+/**
+ * @author ingridnunes
+ *
+ */
+public interface LogicalExpression extends Serializable, Concept, ContentElement {
+
+ public Boolean getValue(BeliefBase beliefBase);
+
+ public Boolean getValue(Map<Object, Object> values);
+
+}
diff --git a/bdi-jade-extensions/src/bdi4jade/extension/palliative/logics/MathExpression.java b/bdi-jade-extensions/src/bdi4jade/extension/palliative/logics/MathExpression.java
new file mode 100644
index 0000000..2f87ec2
--- /dev/null
+++ b/bdi-jade-extensions/src/bdi4jade/extension/palliative/logics/MathExpression.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.extension.palliative.logics;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import bdi4jade.belief.Belief;
+import bdi4jade.belief.BeliefBase;
+import bdi4jade.extension.palliative.logics.MathExpression.Operator;
+
+/**
+ * @author ingridnunes
+ *
+ */
+public class MathExpression<T> extends TernaryPredicate<T, Operator, Double> {
+
+ private static final long serialVersionUID = 11514826399908986L;
+
+ public enum Operator {
+
+ EQUAL_TO, NOT_EQUAL_TO, LESS_THAN, LESS_THAN_OR_EQUAL_TO, GREATER_THAN, GREATER_THAN_OR_EQUAL_TO;
+
+ }
+
+ public MathExpression() {
+
+ }
+
+ public MathExpression(T freeVariable, Operator operator, Double value) {
+ super(freeVariable, operator, value);
+ }
+
+ @Override
+ public Boolean getValue(BeliefBase beliefBase) {
+ Belief<T, Double> belief = (Belief<T, Double>) beliefBase.getBelief(getVariable1());
+ Map<Object, Object> values = new HashMap<>();
+ values.put(getVariable1(), belief.getValue());
+ return getValue(beliefBase);
+ }
+
+ @Override
+ public Boolean getValue(Map<Object, Object> values) {
+ Double variableValue = (Double) values.get(getVariable1());
+ switch (getVariable2()) {
+ case EQUAL_TO:
+ return variableValue == getVariable3();
+ case NOT_EQUAL_TO:
+ return variableValue != getVariable3();
+ case LESS_THAN:
+ return variableValue < getVariable3();
+ case LESS_THAN_OR_EQUAL_TO:
+ return variableValue <= getVariable3();
+ case GREATER_THAN:
+ return variableValue > getVariable3();
+ case GREATER_THAN_OR_EQUAL_TO:
+ return variableValue >= getVariable3();
+ }
+ return null;
+ }
+
+}
diff --git a/bdi-jade-extensions/src/bdi4jade/extension/palliative/logics/Not.java b/bdi-jade-extensions/src/bdi4jade/extension/palliative/logics/Not.java
new file mode 100644
index 0000000..8cc676b
--- /dev/null
+++ b/bdi-jade-extensions/src/bdi4jade/extension/palliative/logics/Not.java
@@ -0,0 +1,65 @@
+//----------------------------------------------------------------------------
+// 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.extension.palliative.logics;
+
+import java.util.Map;
+
+import bdi4jade.belief.BeliefBase;
+
+/**
+ * @author ingridnunes
+ *
+ */
+public class Not extends UnaryLogicalExpression {
+
+ public Not() {
+
+ }
+
+ public Not(LogicalExpression expression) {
+ super(expression);
+ }
+
+ @Override
+ public Boolean getValue(BeliefBase beliefBase) {
+ return !getExpression().getValue(beliefBase);
+ }
+
+ @Override
+ public Boolean getValue(Map<Object, Object> values) {
+ return !getExpression().getValue(values);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see java.lang.Object#toString()
+ */
+ @Override
+ public String toString() {
+ StringBuffer sb = new StringBuffer();
+ sb.append("!").append(expression);
+ return sb.toString();
+ }
+
+}
diff --git a/bdi-jade-extensions/src/bdi4jade/extension/palliative/logics/Or.java b/bdi-jade-extensions/src/bdi4jade/extension/palliative/logics/Or.java
new file mode 100644
index 0000000..c1da5e9
--- /dev/null
+++ b/bdi-jade-extensions/src/bdi4jade/extension/palliative/logics/Or.java
@@ -0,0 +1,65 @@
+//----------------------------------------------------------------------------
+// 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.extension.palliative.logics;
+
+import java.util.Map;
+
+import bdi4jade.belief.BeliefBase;
+
+/**
+ * @author ingridnunes
+ *
+ */
+public class Or extends BinaryLogicalExpression {
+
+ public Or() {
+
+ }
+
+ public Or(LogicalExpression expression1, LogicalExpression expression2) {
+ super(expression1, expression2);
+ }
+
+ @Override
+ public Boolean getValue(BeliefBase beliefBase) {
+ return getExpression1().getValue(beliefBase) || getExpression2().getValue(beliefBase);
+ }
+
+ @Override
+ public Boolean getValue(Map<Object, Object> values) {
+ return getExpression1().getValue(values) || getExpression2().getValue(values);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see java.lang.Object#toString()
+ */
+ @Override
+ public String toString() {
+ StringBuffer sb = new StringBuffer();
+ sb.append("(").append(expression1).append(" v ").append(expression2).append(")");
+ return sb.toString();
+ }
+
+}
diff --git a/bdi-jade-extensions/src/bdi4jade/extension/palliative/logics/Predicate.java b/bdi-jade-extensions/src/bdi4jade/extension/palliative/logics/Predicate.java
new file mode 100644
index 0000000..4938bbe
--- /dev/null
+++ b/bdi-jade-extensions/src/bdi4jade/extension/palliative/logics/Predicate.java
@@ -0,0 +1,64 @@
+//----------------------------------------------------------------------------
+// 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.extension.palliative.logics;
+
+import java.util.Map;
+
+import bdi4jade.belief.BeliefBase;
+import bdi4jade.belief.PredicateBelief;
+
+/**
+ * @author ingridnunes
+ *
+ */
+public abstract class Predicate implements LogicalExpression {
+
+ public String getStatement() {
+ return toString();
+ }
+
+ @Override
+ public Boolean getValue(BeliefBase beliefBase) {
+ PredicateBelief<Predicate> belief = (PredicateBelief<Predicate>) beliefBase.getBelief(this);
+ if (belief != null) {
+ return belief.getValue();
+ }
+ return null;
+ }
+
+ @Override
+ public Boolean getValue(Map<Object, Object> values) {
+ return (Boolean) values.get(this);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see java.lang.Object#toString()
+ */
+ @Override
+ public String toString() {
+ return this.getClass().getSimpleName();
+ }
+
+}
diff --git a/bdi-jade-extensions/src/bdi4jade/extension/palliative/logics/Proposition.java b/bdi-jade-extensions/src/bdi4jade/extension/palliative/logics/Proposition.java
new file mode 100644
index 0000000..4f5ea9a
--- /dev/null
+++ b/bdi-jade-extensions/src/bdi4jade/extension/palliative/logics/Proposition.java
@@ -0,0 +1,41 @@
+//----------------------------------------------------------------------------
+// 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.extension.palliative.logics;
+
+/**
+ * @author ingridnunes
+ *
+ */
+public class Proposition extends Predicate {
+
+ @Override
+ public boolean equals(Object obj) {
+ return (obj == null || !(obj instanceof Proposition) || !this.getClass().equals(obj.getClass()));
+ }
+
+ @Override
+ public int hashCode() {
+ return this.getClass().hashCode();
+ }
+
+}
diff --git a/bdi-jade-extensions/src/bdi4jade/extension/palliative/logics/TernaryPredicate.java b/bdi-jade-extensions/src/bdi4jade/extension/palliative/logics/TernaryPredicate.java
new file mode 100644
index 0000000..b5e9a07
--- /dev/null
+++ b/bdi-jade-extensions/src/bdi4jade/extension/palliative/logics/TernaryPredicate.java
@@ -0,0 +1,50 @@
+package bdi4jade.extension.palliative.logics;
+
+public abstract class TernaryPredicate<T, U, V> extends BinaryPredicate<T, U> {
+
+ private static final long serialVersionUID = -1506723105103606268L;
+
+ protected V variable3;
+
+ public TernaryPredicate() {
+
+ }
+
+ public TernaryPredicate(T first, U second, V third) {
+ super(first, second);
+ this.variable3 = third;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (obj != null && this.getClass().equals(obj.getClass())) {
+ TernaryPredicate<?, ?, ?> p = (TernaryPredicate<?, ?, ?>) obj;
+ return this.variable1.equals(p.variable1) && this.variable2.equals(p.variable2)
+ && this.variable3.equals(p.variable3);
+ }
+ return false;
+ }
+
+ public V getVariable3() {
+ return variable3;
+ }
+
+ @Override
+ public int hashCode() {
+ final int prime = 31;
+ int result = super.hashCode();
+ result = prime * result + ((variable3 == null) ? 0 : variable3.hashCode());
+ return result;
+ }
+
+ public void setVariable3(V variable3) {
+ this.variable3 = variable3;
+ }
+
+ protected void appendVariables(StringBuffer sb) {
+ super.appendVariables(sb);
+ sb.append(",");
+ sb.append(variable3);
+ }
+
+}
\ No newline at end of file
diff --git a/bdi-jade-extensions/src/bdi4jade/extension/palliative/logics/UnaryLogicalExpression.java b/bdi-jade-extensions/src/bdi4jade/extension/palliative/logics/UnaryLogicalExpression.java
new file mode 100644
index 0000000..b4852c4
--- /dev/null
+++ b/bdi-jade-extensions/src/bdi4jade/extension/palliative/logics/UnaryLogicalExpression.java
@@ -0,0 +1,56 @@
+//----------------------------------------------------------------------------
+// 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.extension.palliative.logics;
+
+/**
+ * @author ingridnunes
+ *
+ */
+public abstract class UnaryLogicalExpression implements LogicalExpression {
+
+ protected LogicalExpression expression;
+
+ public UnaryLogicalExpression() {
+
+ }
+
+ public UnaryLogicalExpression(LogicalExpression expression) {
+ this.expression = expression;
+ }
+
+ /**
+ * @return the expression
+ */
+ public LogicalExpression getExpression() {
+ return expression;
+ }
+
+ /**
+ * @param expression
+ * the expression to set
+ */
+ public void setExpression(LogicalExpression expression) {
+ this.expression = expression;
+ }
+
+}
diff --git a/bdi-jade-extensions/src/bdi4jade/extension/palliative/logics/UnaryPredicate.java b/bdi-jade-extensions/src/bdi4jade/extension/palliative/logics/UnaryPredicate.java
new file mode 100644
index 0000000..d60cbe1
--- /dev/null
+++ b/bdi-jade-extensions/src/bdi4jade/extension/palliative/logics/UnaryPredicate.java
@@ -0,0 +1,100 @@
+//----------------------------------------------------------------------------
+// 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.extension.palliative.logics;
+
+import java.util.Map;
+
+import bdi4jade.belief.BeliefBase;
+import bdi4jade.belief.PredicateBelief;
+
+/**
+ * @author Ingrid Nunes
+ */
+public abstract class UnaryPredicate<T> extends Predicate {
+
+ private static final long serialVersionUID = -1506723105103606268L;
+
+ protected T variable;
+
+ public UnaryPredicate() {
+
+ }
+
+ public UnaryPredicate(T concept) {
+ this.variable = concept;
+ }
+
+ protected void appendVariables(StringBuffer sb) {
+ sb.append(variable);
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (obj != null && this.getClass().equals(obj.getClass())) {
+ UnaryPredicate<?> p = (UnaryPredicate<?>) obj;
+ return this.variable.equals(p.variable);
+ }
+ return false;
+ }
+
+ @Override
+ public Boolean getValue(BeliefBase beliefBase) {
+ PredicateBelief<Predicate> belief = (PredicateBelief<Predicate>) beliefBase.getBelief(this);
+ if (belief != null) {
+ return belief.getValue();
+ }
+ return null;
+ }
+
+ @Override
+ public Boolean getValue(Map<Object, Object> values) {
+ return (Boolean) values.get(this);
+ }
+
+ public T getVariable() {
+ return variable;
+ }
+
+ @Override
+ public int hashCode() {
+ final int prime = 31;
+ int result = 1;
+ result = prime * result + ((this.getClass() == null) ? 0 : this.getClass().hashCode());
+ result = prime * result + ((variable == null) ? 0 : variable.hashCode());
+ return result;
+ }
+
+ public void setConcept(T concept) {
+ this.variable = concept;
+ }
+
+ @Override
+ public String toString() {
+ StringBuffer sb = new StringBuffer();
+ sb.append(super.toString());
+ sb.append("(");
+ appendVariables(sb);
+ sb.append(")");
+ return sb.toString();
+ }
+
+}
diff --git a/bdi-jade-extensions/src/bdi4jade/extension/palliative/NamedResource.java b/bdi-jade-extensions/src/bdi4jade/extension/palliative/NamedResource.java
new file mode 100644
index 0000000..b9773f8
--- /dev/null
+++ b/bdi-jade-extensions/src/bdi4jade/extension/palliative/NamedResource.java
@@ -0,0 +1,101 @@
+package bdi4jade.extension.palliative;
+
+import bdi4jade.core.MetadataElement;
+import bdi4jade.core.MetadataElementImpl;
+
+/**
+ * This class provides a default implementation for a resource, representing it
+ * just with a given name.
+ *
+ * It implements the {@link MetadataElement} interface, allowing to associate
+ * metadata with resources.
+ *
+ * @author Ingrid Nunes
+ *
+ */
+public class NamedResource extends MetadataElementImpl implements Resource, MetadataElement {
+
+ private static final long serialVersionUID = 3958189054716876043L;
+
+ private String name;
+
+ /**
+ * The default constructor. It should be only used if persistence frameworks
+ * are used.
+ */
+ protected NamedResource() {
+
+ }
+
+ /**
+ * Initializes a resource with its name.
+ *
+ * @param name
+ * the resource name.
+ */
+ public NamedResource(String name) {
+ this.name = name;
+ }
+
+ /**
+ * Returns true of the object is a named resource and has the same name of
+ * this named resource.
+ *
+ * @param obj
+ * to object to be tested if it is equal to this named resource.
+ *
+ * @see Object#equals(Object)
+ */
+ @Override
+ public final boolean equals(Object obj) {
+ if (obj instanceof NamedResource) {
+ NamedResource sg = (NamedResource) obj;
+ return this.name.equals(sg.name);
+ }
+ return false;
+ }
+
+ /**
+ * Returns the name of this resource.
+ *
+ * @return the name.
+ */
+ public String getName() {
+ return name;
+ }
+
+ /**
+ * Returns the hash code of this named resource.
+ *
+ * @return the hash code of the name of this resource.
+ *
+ * @see java.lang.Object#hashCode()
+ */
+ @Override
+ public final int hashCode() {
+ return name == null ? 0 : this.name.hashCode();
+ }
+
+ /**
+ * Sets the name of this resource. Ideally, the name should be final and
+ * initialized in the constructor. This method should be only used if
+ * persistence frameworks are used.
+ *
+ * @param name
+ * the name to set.
+ */
+ protected void setName(String name) {
+ this.name = name;
+ }
+
+ /**
+ * Returns the string representation of this resource, which is its name.
+ *
+ * @see java.lang.Object#toString()
+ */
+ @Override
+ public String toString() {
+ return name;
+ }
+
+}
\ No newline at end of file
diff --git a/bdi-jade-extensions/src/bdi4jade/extension/palliative/PalliativeCapability.java b/bdi-jade-extensions/src/bdi4jade/extension/palliative/PalliativeCapability.java
new file mode 100644
index 0000000..58829aa
--- /dev/null
+++ b/bdi-jade-extensions/src/bdi4jade/extension/palliative/PalliativeCapability.java
@@ -0,0 +1,24 @@
+package bdi4jade.extension.palliative;
+
+import bdi4jade.annotation.Belief;
+import bdi4jade.core.Capability;
+import bdi4jade.extension.palliative.graph.CauseEffectKnowledgeModel;
+import bdi4jade.extension.palliative.reasoning.PalliativeOptionGenerationFunction;
+import bdi4jade.extension.palliative.reasoning.PalliativePlanSelectionStrategy;
+
+public class PalliativeCapability extends Capability {
+
+ private static final long serialVersionUID = -1818834346847016992L;
+
+ @Belief(name = CauseEffectKnowledgeModel.NAME)
+ protected CauseEffectKnowledgeModel causeEffectKnowledgeModel = new CauseEffectKnowledgeModel();
+
+ @Belief(name = ResourcePreferences.NAME)
+ protected ResourcePreferences preferences = new ResourcePreferences();
+
+ public PalliativeCapability() {
+ setOptionGenerationFunction(new PalliativeOptionGenerationFunction(this));
+ setPlanSelectionStrategy(new PalliativePlanSelectionStrategy(this));
+ }
+
+}
diff --git a/bdi-jade-extensions/src/bdi4jade/extension/palliative/PlanRequiredResource.java b/bdi-jade-extensions/src/bdi4jade/extension/palliative/PlanRequiredResource.java
new file mode 100644
index 0000000..94abec9
--- /dev/null
+++ b/bdi-jade-extensions/src/bdi4jade/extension/palliative/PlanRequiredResource.java
@@ -0,0 +1,33 @@
+package bdi4jade.extension.palliative;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Set;
+
+public class PlanRequiredResource {
+
+ public static final String METADATA_NAME = PlanRequiredResource.class.getSimpleName();
+
+ private final Map<Resource, Double> requiredResources;
+
+ public PlanRequiredResource() {
+ this.requiredResources = new HashMap<>();
+ }
+
+ public Double getRequiredResource(Resource resource) {
+ return this.requiredResources.get(resource);
+ }
+
+ public Map<Resource, Double> getRequiredResources() {
+ return requiredResources;
+ }
+
+ public Set<Resource> getResources() {
+ return requiredResources.keySet();
+ }
+
+ public void setRequiredResource(Resource resource, Double value) {
+ this.requiredResources.put(resource, value);
+ }
+
+}
diff --git a/bdi-jade-extensions/src/bdi4jade/extension/palliative/reasoning/PalliativeOptionGenerationFunction.java b/bdi-jade-extensions/src/bdi4jade/extension/palliative/reasoning/PalliativeOptionGenerationFunction.java
new file mode 100644
index 0000000..fe42cbe
--- /dev/null
+++ b/bdi-jade-extensions/src/bdi4jade/extension/palliative/reasoning/PalliativeOptionGenerationFunction.java
@@ -0,0 +1,254 @@
+package bdi4jade.extension.palliative.reasoning;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+import bdi4jade.belief.PredicateBelief;
+import bdi4jade.core.Capability;
+import bdi4jade.core.GoalUpdateSet;
+import bdi4jade.core.GoalUpdateSet.GoalDescription;
+import bdi4jade.event.GoalEvent;
+import bdi4jade.event.GoalListener;
+import bdi4jade.extension.palliative.goal.CauseEffectProblem;
+import bdi4jade.extension.palliative.goal.CauseEffectProblem.CauseEffectProblemStatus;
+import bdi4jade.extension.palliative.goal.CauseFactorStatus;
+import bdi4jade.extension.palliative.graph.AlternativeCauseSet;
+import bdi4jade.extension.palliative.graph.CauseEffectKnowledgeModel;
+import bdi4jade.extension.palliative.graph.CauseEffectRelationship;
+import bdi4jade.extension.palliative.logics.Fact;
+import bdi4jade.goal.Goal;
+import bdi4jade.goal.GoalStatus;
+import bdi4jade.goal.NestedGoal;
+import bdi4jade.goal.PredicateGoal;
+import bdi4jade.reasoning.OptionGenerationFunction;
+
+public class PalliativeOptionGenerationFunction implements OptionGenerationFunction {
+
+ private Capability capability;
+ private final Map<Goal, CauseEffectProblem> causeEffectProblems;
+
+ public PalliativeOptionGenerationFunction(Capability capability) {
+ setCapability(capability);
+ this.causeEffectProblems = new HashMap<>();
+ }
+
+ private CauseEffectKnowledgeModel getCauseEffectKnowledgeModel() {
+ return (CauseEffectKnowledgeModel) this.capability.getBeliefBase().getBelief(CauseEffectKnowledgeModel.NAME);
+ }
+
+ private Boolean causeFinished(Collection<CauseFactorStatus> causeEffectStatus) {
+ for (CauseFactorStatus causeFactor : causeEffectStatus) {
+ if (causeFactor.getUpdatedStatus() == null || !causeFactor.getUpdatedStatus()) {
+ return Boolean.FALSE;
+ }
+ }
+ return Boolean.TRUE;
+ }
+
+ private Boolean causeNotFound(Collection<CauseFactorStatus> causeEffectStatus) {
+ boolean existUnachievable = false;
+ boolean existOnGoing = false;
+ for (CauseFactorStatus causeFactor : causeEffectStatus) {
+ if (causeFactor.getInitialStatus() == null) {
+ if (causeFactor.getTestGoal() != null) {
+ if (causeFactor.getTestGoalStatus() != null) {
+ existUnachievable = true;
+ } else {
+ existOnGoing = true;
+ }
+ }
+ }
+ }
+ return existUnachievable && !existOnGoing;
+ }
+
+ @Override
+ public void generateGoals(GoalUpdateSet goalUpdateSet) {
+
+ // Algorithm 1 - lines 2-5
+ for (GoalDescription goalDescription : goalUpdateSet.getCurrentGoals()) {
+ Goal goal = goalDescription.getGoal();
+ Goal parentGoal = null;
+ if (goal instanceof NestedGoal) {
+ parentGoal = goal;
+ goal = ((NestedGoal) goal).getGoal();
+ }
+
+ CauseEffectProblem cep = this.causeEffectProblems.get(goal);
+ CauseEffectRelationship cer = getCauseEffectKnowledgeModel().getCauseEffectRelationship(goal);
+ if (cep == null && cer != null) {
+ cep = new CauseEffectProblem((PredicateGoal<?>) goal, cer, capability.getMyAgent(), parentGoal);
+ causeEffectProblems.put(cep.getEffectGoal(), cep);
+ }
+
+ }
+
+ Collection<CauseEffectProblem> problems = new ArrayList<>(causeEffectProblems.values());
+ for (CauseEffectProblem cep : problems) {
+ // Algorithm 1 - lines 7-17
+ for (CauseFactorStatus causeFactor : cep.getCauseFactorStatus()) {
+ updateCauseFactor(causeFactor);
+ }
+
+ // Algorithm 1 - lines 18-35
+ if (cep.getEffectGoalStatus() != null) {
+ if (knownCause(cep, cep.getCauseEffectRelationship())) {
+ if (causeFinished(cep.getCauseFactorStatus())) {
+ setEndState(cep);
+ causeEffectProblems.remove(cep.getEffectGoal());
+ } else {
+ for (CauseFactorStatus causeFactor : cep.getCauseFactorStatus()) {
+ if (!causeFactor.getUpdatedStatus() && causeFactor.getAchievementGoal() == null) {
+ Goal achievementGoal = causeFactor.generateAchievementGoal();
+ GoalListener listener = new GoalListener() {
+ @Override
+ public void goalPerformed(GoalEvent event) {
+ if (event.getStatus().isFinished()) {
+ causeFactor.setAchievementGoalStatus(event.getStatus());
+ }
+ }
+ };
+ goalUpdateSet.generateGoal(achievementGoal, capability, listener);
+ }
+ }
+ }
+ } else if (causeNotFound(cep.getCauseFactorStatus())) {
+ setEndState(cep);
+ causeEffectProblems.remove(cep);
+ } else {
+ for (CauseFactorStatus causeFactor : cep.getCauseFactorStatus()) {
+ if (causeFactor.getInitialStatus() == null && causeFactor.getTestGoal() == null) {
+ Goal testGoal = causeFactor.generateTestGoal();
+ GoalListener listener = new GoalListener() {
+ @Override
+ public void goalPerformed(GoalEvent event) {
+ if (event.getStatus().isFinished()) {
+ causeFactor.setTestGoalStatus(event.getStatus());
+ }
+ }
+ };
+ goalUpdateSet.generateGoal(testGoal, capability, listener);
+ }
+ }
+ }
+ }
+
+ }
+ }
+
+ private Boolean knownCause(CauseEffectProblem cep, CauseEffectRelationship cer) {
+ for (CauseFactorStatus cf : cep.getCauseFactorStatus()) {
+ if (cf.getInitialStatus() == null) {
+ return Boolean.FALSE;
+ }
+ }
+
+ Set<CauseFactorStatus> currentCauses = new HashSet<>();
+
+ for (Fact fact : cer.getMandatoryCauses()) {
+ CauseFactorStatus cf = cep.getCauseFactorStatus(fact);
+ if (!cf.getInitialStatus()) {
+ return Boolean.FALSE;
+ } else {
+ currentCauses.add(cf);
+ }
+ }
+
+ for (Fact fact : cer.getOptionalCauses()) {
+ CauseFactorStatus cf = cep.getCauseFactorStatus(fact);
+ if (cf.getInitialStatus()) {
+ currentCauses.add(cf);
+ }
+ }
+
+ for (AlternativeCauseSet acs : cer.getAlternativeCauseSets()) {
+ Set<CauseFactorStatus> alternativeCauses = new HashSet<>();
+ for (Fact fact : acs.getAlternativeCauses()) {
+ CauseFactorStatus cf = cep.getCauseFactorStatus(fact);
+ if (cf.getInitialStatus()) {
+ alternativeCauses.add(cf);
+ currentCauses.add(cf);
+ }
+ if (alternativeCauses.size() < acs.getMin() || alternativeCauses.size() > acs.getMax()) {
+ return Boolean.FALSE;
+ }
+ }
+ }
+
+ cep.setCauseFactorStatus(currentCauses);
+ 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();
+
+ boolean existsResolved = false;
+ boolean existsUnresolved = false;
+ for (CauseFactorStatus causeFactor : causeEffectStatus) {
+ if (causeFactor.getUpdatedStatus()) {
+ existsResolved = true;
+ } else {
+ existsUnresolved = true;
+ }
+ }
+
+ if (effectStatus.equals(GoalStatus.ACHIEVED)) {
+ if (!existsResolved) {
+ cep.setStatus(CauseEffectProblemStatus.MITIGATED);
+ } else if (!existsUnresolved) {
+ cep.setStatus(CauseEffectProblemStatus.FULLY_RESOLVED);
+ } else {
+ cep.setStatus(CauseEffectProblemStatus.PARTIALLY_RESOLVED);
+ }
+ } else {
+ if (!existsResolved) {
+ cep.setStatus(CauseEffectProblemStatus.UNSUCCESSFUL);
+ } else if (!existsUnresolved) {
+ cep.setStatus(CauseEffectProblemStatus.CAUSE_RESOLVED);
+ } else {
+ cep.setStatus(CauseEffectProblemStatus.CAUSE_PARTIALLY_RESOLVED);
+ }
+ }
+ System.out.println(cep);
+ }
+
+ private void updateCauseFactor(CauseFactorStatus cf) {
+ PredicateBelief<?> belief = (PredicateBelief<?>) this.capability.getBeliefBase()
+ .getBelief(cf.getFact().getPredicate());
+ if (belief == null)
+ return;
+
+ // Algorithm 1 - lines 8-12
+ if (cf.getInitialStatus() == null) {
+ if (belief.getValue().equals(cf.getFact().getValue())) {
+ cf.setInitialStatus(Boolean.TRUE);
+ } else {
+ cf.setInitialStatus(Boolean.FALSE);
+ }
+ cf.setUpdatedStatus(Boolean.FALSE);
+ // Algorithm 1 - lines 13-17
+ } else {
+ if ((cf.getInitialStatus() && belief.getValue().equals(!cf.getFact().getValue()))
+ || (!cf.getInitialStatus() && belief.getValue().equals(cf.getFact().getValue()))) {
+ cf.setUpdatedStatus(Boolean.TRUE);
+ }
+ }
+ }
+
+}
diff --git a/bdi-jade-extensions/src/bdi4jade/extension/palliative/reasoning/PalliativePlanSelectionStrategy.java b/bdi-jade-extensions/src/bdi4jade/extension/palliative/reasoning/PalliativePlanSelectionStrategy.java
new file mode 100644
index 0000000..0c293c0
--- /dev/null
+++ b/bdi-jade-extensions/src/bdi4jade/extension/palliative/reasoning/PalliativePlanSelectionStrategy.java
@@ -0,0 +1,152 @@
+package bdi4jade.extension.palliative.reasoning;
+
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+import bdi4jade.core.Capability;
+import bdi4jade.extension.palliative.PlanRequiredResource;
+import bdi4jade.extension.palliative.Resource;
+import bdi4jade.extension.palliative.ResourcePreferences;
+import bdi4jade.extension.palliative.goal.ConstrainedGoal;
+import bdi4jade.extension.palliative.goal.ObjectiveFunction;
+import bdi4jade.extension.palliative.logics.And;
+import bdi4jade.extension.palliative.logics.LogicalExpression;
+import bdi4jade.goal.Goal;
+import bdi4jade.plan.Plan;
+import bdi4jade.reasoning.DefaultPlanSelectionStrategy;
+import bdi4jade.reasoning.PlanSelectionStrategy;
+
+public class PalliativePlanSelectionStrategy extends DefaultPlanSelectionStrategy implements PlanSelectionStrategy {
+
+ private class Boundary {
+ public final Double max;
+ public final Double min;
+
+ public Boundary(Double min, Double max) {
+ this.min = min;
+ this.max = max;
+ }
+ }
+
+ public PalliativePlanSelectionStrategy(Capability capability) {
+ setCapability(capability);
+ }
+
+ private Map<Resource, Boundary> getBoundaries(Set<Resource> resources, Set<Plan> plans) {
+ Map<Resource, Boundary> boundaries = new HashMap<>();
+
+ for (Resource resource : resources) {
+ boundaries.put(resource, new Boundary(getMinBoundary(resource, plans), getMaxBoundary(resource, plans)));
+ }
+ return boundaries;
+ }
+
+ private Set<Plan> getCandidatePlans(ConstrainedGoal goal, Set<Resource> resources, Set<Plan> plans) {
+ Set<Plan> candidatePlans = new HashSet<>();
+
+ LogicalExpression constraint = null;
+ for (LogicalExpression c : goal.getOperationConstraints()) {
+ if (constraint == null) {
+ constraint = c;
+ } else {
+ c = new And(c, constraint);
+ }
+ }
+
+ for (Plan plan : plans) {
+ PlanRequiredResource prr = (PlanRequiredResource) plan.getMetadata(PlanRequiredResource.METADATA_NAME);
+ if (prr == null) {
+ candidatePlans.add(plan);
+ } else {
+ // FIXME haven't tested
+ Map<Object, Object> values = new HashMap<>();
+ values.putAll(prr.getRequiredResources());
+ if (constraint != null && constraint.getValue(values)) {
+ candidatePlans.add(plan);
+ }
+ }
+ }
+
+ return candidatePlans;
+ }
+
+ private Double getMaxBoundary(Resource resource, Set<Plan> plans) {
+ Double max = null;
+ for (Plan plan : plans) {
+ PlanRequiredResource prr = (PlanRequiredResource) plan.getMetadata(PlanRequiredResource.METADATA_NAME);
+ if (prr == null) {
+ continue;
+ }
+ Double requiredResource = prr.getRequiredResource(resource);
+ if (requiredResource != null && (max == null || max < requiredResource)) {
+ max = requiredResource;
+ }
+ }
+ return max;
+ }
+
+ private Double getMinBoundary(Resource resource, Set<Plan> plans) {
+ Double min = null;
+ for (Plan plan : plans) {
+ PlanRequiredResource prr = (PlanRequiredResource) plan.getMetadata(PlanRequiredResource.METADATA_NAME);
+ if (prr == null) {
+ continue;
+ }
+ Double requiredResource = prr.getRequiredResource(resource);
+ if (requiredResource != null && (min == null || min > requiredResource)) {
+ min = requiredResource;
+ }
+ }
+ return min;
+ }
+
+ @SuppressWarnings("unchecked")
+ @Override
+ public Plan selectPlan(Goal goal, Set<Plan> capabilityPlans) {
+ if (goal instanceof ConstrainedGoal) {
+ ConstrainedGoal g_c = (ConstrainedGoal) goal;
+ ResourcePreferences preferences = (ResourcePreferences) capability.getBeliefBase()
+ .getBelief(ResourcePreferences.NAME);
+ Map<Resource, Boundary> boundaries = getBoundaries(preferences.getResources(), capabilityPlans);
+
+ Set<Plan> candidatePlans = getCandidatePlans(g_c, preferences.getResources(), capabilityPlans);
+
+ Plan selectedPlan = null;
+ Double maxUtility = null;
+ for (Plan plan : candidatePlans) {
+ double utility = 0;
+
+ for (Resource resource : preferences.getResources()) {
+ ObjectiveFunction obj = g_c.getObjectiveFunction().get(resource);
+ if (obj == null) {
+ continue;
+ }
+
+ Double prr = ((PlanRequiredResource) plan.getMetadata(PlanRequiredResource.METADATA_NAME))
+ .getRequiredResource(resource);
+ Double preference = preferences.getPreferenceForResource(resource);
+ Boundary boundary = boundaries.get(resource);
+
+ if (preference != null) {
+ double value = (prr - boundary.min) / ((boundary.max - boundary.min));
+ if (obj.equals(ObjectiveFunction.MINIMIZE)) {
+ value = 1 - value;
+ }
+ utility += preference * value;
+ }
+
+ if (selectedPlan == null || maxUtility < utility) {
+ selectedPlan = plan;
+ maxUtility = utility;
+ }
+ }
+ }
+ return selectedPlan;
+ } else {
+ return super.selectPlan(goal, capabilityPlans);
+ }
+ }
+
+}
diff --git a/bdi-jade-extensions/src/bdi4jade/extension/palliative/Resource.java b/bdi-jade-extensions/src/bdi4jade/extension/palliative/Resource.java
new file mode 100644
index 0000000..d60c94e
--- /dev/null
+++ b/bdi-jade-extensions/src/bdi4jade/extension/palliative/Resource.java
@@ -0,0 +1,10 @@
+package bdi4jade.extension.palliative;
+
+import java.io.Serializable;
+
+import jade.content.Concept;
+import jade.content.ContentElement;
+
+public interface Resource extends Serializable, Concept, ContentElement {
+
+}
diff --git a/bdi-jade-extensions/src/bdi4jade/extension/palliative/ResourcePreferences.java b/bdi-jade-extensions/src/bdi4jade/extension/palliative/ResourcePreferences.java
new file mode 100644
index 0000000..f508df1
--- /dev/null
+++ b/bdi-jade-extensions/src/bdi4jade/extension/palliative/ResourcePreferences.java
@@ -0,0 +1,31 @@
+package bdi4jade.extension.palliative;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Set;
+
+import bdi4jade.belief.TransientBelief;
+
+public class ResourcePreferences extends TransientBelief<String, Map<Resource, Double>> {
+
+ public static final String NAME = "ResourcePreferences";
+
+ private static final long serialVersionUID = -3150138426400180011L;
+
+ public ResourcePreferences() {
+ super(NAME, new HashMap<Resource, Double>());
+ }
+
+ public Double getPreferenceForResource(Resource resource) {
+ return this.value.get(resource);
+ }
+
+ public Set<Resource> getResources() {
+ return getValue().keySet();
+ }
+
+ public void setPreferenceForResource(Resource resource, Double preference) {
+ this.value.put(resource, preference);
+ }
+
+}