package jadex.bdi.runtime.interpreter;
import jadex.bdi.model.OAVBDIMetaModel;
import jadex.bdi.runtime.ICandidateInfo;
import jadex.bdi.runtime.impl.flyweights.PlanFlyweight;
import jadex.bdi.runtime.impl.flyweights.PlanInfoFlyweight;
import jadex.bdi.runtime.impl.flyweights.PlanInstanceInfoFlyweight;
import jadex.commons.SUtil;
import jadex.commons.collection.SCollection;
import jadex.javaparser.IValueFetcher;
import jadex.rules.rulesystem.IAction;
import jadex.rules.rulesystem.ICondition;
import jadex.rules.rulesystem.IVariableAssignments;
import jadex.rules.rulesystem.rules.AndCondition;
import jadex.rules.rulesystem.rules.BoundConstraint;
import jadex.rules.rulesystem.rules.FunctionCall;
import jadex.rules.rulesystem.rules.IConstraint;
import jadex.rules.rulesystem.rules.IOperator;
import jadex.rules.rulesystem.rules.LiteralConstraint;
import jadex.rules.rulesystem.rules.LiteralReturnValueConstraint;
import jadex.rules.rulesystem.rules.NotCondition;
import jadex.rules.rulesystem.rules.ObjectCondition;
import jadex.rules.rulesystem.rules.OrConstraint;
import jadex.rules.rulesystem.rules.Rule;
import jadex.rules.rulesystem.rules.Variable;
import jadex.rules.state.IOAVState;
import jadex.rules.state.OAVAttributeType;
import jadex.rules.state.OAVJavaType;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
/**
* Static helper class for event processing rules and actions.
* Rules that handle the event processing, i.e.
* - building an APL (applicable plan list) for goals / metagoals / internal events / message events
* - selecting a plan candidate for execution
* - handle meta-level reasoning (process for selecting a candidate)
* - scheduling the selected candidate
*/
public class EventProcessingRules
{
//-------- RPlan/Waitqueue APL building rules --------
/**
* Action to add matching rplan to apl.
*/
protected static IAction ADD_RPLAN_TO_APL = new IAction()
{
public void execute(IOAVState state, IVariableAssignments assignments)
{
Object rpe = assignments.getVariableValue("?rpe");
// Object ragent = assignments.getVariableValue("?ragent");
Object rplan = assignments.getVariableValue("?rplan");
Object rcapa = assignments.getVariableValue("?rcapa");
// state.setAttributeValue(ragent, OAVBDIRuntimeModel.agent_has_eventprocessing, rpe);
Object apl = state.getAttributeValue(rpe, OAVBDIRuntimeModel.processableelement_has_apl);
if(apl==null)
{
apl = state.createObject(OAVBDIRuntimeModel.apl_type);
state.setAttributeValue(rpe, OAVBDIRuntimeModel.processableelement_has_apl, apl);
}
Object cand = state.createObject(OAVBDIRuntimeModel.plancandidate_type);
state.setAttributeValue(cand, OAVBDIRuntimeModel.plancandidate_has_plan, rplan);
state.setAttributeValue(cand, OAVBDIRuntimeModel.plancandidate_has_rcapa, rcapa);
state.addAttributeValue(apl, OAVBDIRuntimeModel.apl_has_planinstancecandidates, cand);
}
};
/**
* Action to set rplan apl building to finished.
* /
protected static IAction NO_RPLANS_FOR_APL = new IAction()
{
public void execute(IOAVState state, IVariableAssignments assignments)
{
Object rpe = assignments.getVariableValue("?rpe");
// Object ragent = assignments.getVariableValue("?ragent");
// state.setAttributeValue(ragent, OAVBDIRuntimeModel.agent_has_eventprocessing, rpe);
Object apl = state.getAttributeValue(rpe, OAVBDIRuntimeModel.processableelement_has_apl);
if(apl==null)
{
apl = state.createObject(OAVBDIRuntimeModel.apl_type);
state.setAttributeValue(rpe, OAVBDIRuntimeModel.processableelement_has_apl, apl);
}
state.setAttributeValue(rpe, OAVBDIRuntimeModel.processableelement_has_state,
OAVBDIRuntimeModel.PROCESSABLEELEMENT_APLRPLANSREADY);
// state.setAttributeValue(apl, OAVBDIRuntimeModel.apl_has_buildrplansfinished, Boolean.TRUE);
}
};*/
/**
* Action to add matching waitqueue candidate to apl.
*/
protected static IAction ADD_WAITQUEUECAND_TO_APL = new IAction()
{
public void execute(IOAVState state, IVariableAssignments assignments)
{
Object rpe = assignments.getVariableValue("?rpe");
Object rcapa = assignments.getVariableValue("?rcapa");
Object rplan = assignments.getVariableValue("?rplan");
// state.setAttributeValue(ragent, OAVBDIRuntimeModel.agent_has_eventprocessing, rpe);
Object apl = state.getAttributeValue(rpe, OAVBDIRuntimeModel.processableelement_has_apl);
if(apl==null)
{
apl = state.createObject(OAVBDIRuntimeModel.apl_type);
state.setAttributeValue(rpe, OAVBDIRuntimeModel.processableelement_has_apl, apl);
}
Object wc = state.createObject(OAVBDIRuntimeModel.waitqueuecandidate_type);
state.setAttributeValue(wc, OAVBDIRuntimeModel.waitqueuecandidate_has_plan, rplan);
state.setAttributeValue(wc, OAVBDIRuntimeModel.waitqueuecandidate_has_rcapa, rcapa);
state.addAttributeValue(apl, OAVBDIRuntimeModel.apl_has_waitqueuecandidates, wc);
}
};
/**
* Action to set waitqueue candidate apl building to finished.
*/
protected static IAction MAKE_APL_AVAILABLE = new IAction()
{
public void execute(IOAVState state, IVariableAssignments assignments)
{
Object rpe = assignments.getVariableValue("?rpe");
Object rcapa = assignments.getVariableValue("?rcapa");
// Object ragent = assignments.getVariableValue("?ragent");
// state.setAttributeValue(ragent, OAVBDIRuntimeModel.agent_has_eventprocessing, rpe);
Object apl = state.getAttributeValue(rpe, OAVBDIRuntimeModel.processableelement_has_apl);
if(apl==null)
{
apl = state.createObject(OAVBDIRuntimeModel.apl_type);
state.setAttributeValue(rpe, OAVBDIRuntimeModel.processableelement_has_apl, apl);
}
// state.setAttributeValue(apl, OAVBDIRuntimeModel.apl_has_buildwaitqueuecandsfinished, Boolean.TRUE);
addMPlansToAPL(state, rpe, rcapa);
}
};
/**
* Add matching waiting rplans or plans with matching waitqueues to the APL
* of an unprocessed processable element and set the APL to building finished,
* when no more found.
*/
protected static Rule[] createBuildRPlanAPLRules()
{
Variable rpe = new Variable("?rpe", OAVBDIRuntimeModel.processableelement_type);
Variable apl = new Variable("?apl", OAVBDIRuntimeModel.apl_type);
Variable candpi = new Variable("?candpi", OAVBDIRuntimeModel.plancandidate_type);
Variable candwq = new Variable("?candwq", OAVBDIRuntimeModel.waitqueuecandidate_type);
Variable org = new Variable("?org", OAVBDIRuntimeModel.processableelement_type);
Variable mpe = new Variable("?mpe", OAVBDIMetaModel.processableelement_type);
Variable rcapa = new Variable("?rcapa", OAVBDIRuntimeModel.capability_type);
Variable rplan = new Variable("?rplan", OAVBDIRuntimeModel.plan_type);
// Variable wa = new Variable("?wa", OAVBDIRuntimeModel.waitabstraction_type);
// Variable wqwa = new Variable("?wqwa", OAVBDIRuntimeModel.waitabstraction_type);
// Shared conditions
ObjectCondition rpecon = new ObjectCondition(rpe.getType());
rpecon.addConstraint(new BoundConstraint(null, rpe));
rpecon.addConstraint(new BoundConstraint(OAVBDIRuntimeModel.processableelement_has_apl, apl));
rpecon.addConstraint(new BoundConstraint(OAVBDIRuntimeModel.messageevent_has_original, org));
rpecon.addConstraint(new BoundConstraint(OAVBDIRuntimeModel.element_has_model, mpe));
rpecon.addConstraint(new LiteralConstraint(OAVBDIRuntimeModel.processableelement_has_state,
OAVBDIRuntimeModel.PROCESSABLEELEMENT_UNPROCESSED));
ObjectCondition capcon = new ObjectCondition(rcapa.getType());
capcon.addConstraint(new BoundConstraint(null, rcapa));
capcon.addConstraint(new OrConstraint(new IConstraint[]
{
new BoundConstraint(OAVBDIRuntimeModel.capability_has_goals, rpe, IOperator.CONTAINS),
new BoundConstraint(OAVBDIRuntimeModel.capability_has_internalevents, rpe, IOperator.CONTAINS),
new BoundConstraint(OAVBDIRuntimeModel.capability_has_messageevents, rpe, IOperator.CONTAINS)
}));
// ObjectCondition wacon = new ObjectCondition(wa.getType());
// wacon.addConstraint(new BoundConstraint(null, wa));
// wacon.addConstraint(new OrConstraint(new IConstraint[]
// {
// // RPlan waiting for (new) goal not allowed, only goalfinished, which is handled elsewhere.
// new BoundConstraint(OAVBDIRuntimeModel.waitabstraction_has_messageevents, org, IOperator.CONTAINS),
// new BoundConstraint(OAVBDIRuntimeModel.waitabstraction_has_internaleventtypes, mpe, IOperator.CONTAINS),
// new BoundConstraint(OAVBDIRuntimeModel.waitabstraction_has_messageeventtypes, mpe, IOperator.CONTAINS),
// }));
// Conditions for plan instances
ObjectCondition planconwa = new ObjectCondition(rplan.getType());
planconwa.addConstraint(new BoundConstraint(null, rplan));
// planconwa.addConstraint(new BoundConstraint(OAVBDIRuntimeModel.plan_has_waitabstraction, wa));
planconwa.addConstraint(new LiteralConstraint(OAVBDIRuntimeModel.plan_has_processingstate,
OAVBDIRuntimeModel.PLANPROCESSINGTATE_WAITING));
planconwa.addConstraint(new OrConstraint(new IConstraint[]
{
// RPlan waiting for (new) goal not allowed, only goalfinished, which is handled elsewhere.
new BoundConstraint(new OAVAttributeType[]{OAVBDIRuntimeModel.plan_has_waitabstraction, OAVBDIRuntimeModel.waitabstraction_has_messageevents}, org, IOperator.CONTAINS),
new BoundConstraint(new OAVAttributeType[]{OAVBDIRuntimeModel.plan_has_waitabstraction, OAVBDIRuntimeModel.waitabstraction_has_internaleventtypes}, mpe, IOperator.CONTAINS),
new BoundConstraint(new OAVAttributeType[]{OAVBDIRuntimeModel.plan_has_waitabstraction, OAVBDIRuntimeModel.waitabstraction_has_messageeventtypes}, mpe, IOperator.CONTAINS),
}));
ObjectCondition candconpi = new ObjectCondition(candpi.getType());
candconpi.addConstraint(new BoundConstraint(null, candpi));
candconpi.addConstraint(new BoundConstraint(OAVBDIRuntimeModel.plancandidate_has_plan, rplan));
ObjectCondition aplconpi = new ObjectCondition(apl.getType());
aplconpi.addConstraint(new BoundConstraint(null, apl));
aplconpi.addConstraint(new BoundConstraint(OAVBDIRuntimeModel.apl_has_planinstancecandidates, candpi, IOperator.CONTAINS));
// todo: maybe better to ensure the rplan is not already added to wq.
// Here a phase model is assumed that first allows plan instance candidates to be added and the waitqueue candidates.
ObjectCondition aplconpi2 = new ObjectCondition(apl.getType());
aplconpi2.addConstraint(new BoundConstraint(null, apl));
aplconpi2.addConstraint(new LiteralConstraint(OAVBDIRuntimeModel.apl_has_waitqueuecandidates, null, IOperator.NOTEQUAL));
// Rules for plan instances
Rule apl_add_rplan = new Rule("apl_add_rplan",
new AndCondition(new ICondition[]{
// rpecon, capcon, wacon, planconwa,
rpecon, capcon, planconwa,
new NotCondition(new AndCondition(new ICondition[]{candconpi, aplconpi})),
new NotCondition(aplconpi2)}),
ADD_RPLAN_TO_APL);
// Conditions for waitqueue candidates
// ObjectCondition waconwq = new ObjectCondition(wqwa.getType());
// waconwq.addConstraint(new BoundConstraint(null, wqwa));
// waconwq.addConstraint(new OrConstraint(new IConstraint[]
// {
// // RPlan waiting for (new) goal not allowed, only goalfinished, which is handled elsewhere.
// new BoundConstraint(OAVBDIRuntimeModel.waitabstraction_has_messageevents, org, IOperator.CONTAINS),
// new BoundConstraint(OAVBDIRuntimeModel.waitabstraction_has_internaleventtypes, mpe, IOperator.CONTAINS),
// new BoundConstraint(OAVBDIRuntimeModel.waitabstraction_has_messageeventtypes, mpe, IOperator.CONTAINS),
// }));
ObjectCondition planconwq = new ObjectCondition(rplan.getType());
planconwq.addConstraint(new BoundConstraint(null, rplan));
// planconwq.addConstraint(new BoundConstraint(OAVBDIRuntimeModel.plan_has_waitqueuewa, wqwa));
planconwq.addConstraint(new OrConstraint(new IConstraint[]
{
// RPlan waiting for (new) goal not allowed, only goalfinished, which is handled elsewhere.
new BoundConstraint(new OAVAttributeType[]{OAVBDIRuntimeModel.plan_has_waitqueuewa, OAVBDIRuntimeModel.waitabstraction_has_messageevents}, org, IOperator.CONTAINS),
new BoundConstraint(new OAVAttributeType[]{OAVBDIRuntimeModel.plan_has_waitqueuewa, OAVBDIRuntimeModel.waitabstraction_has_internaleventtypes}, mpe, IOperator.CONTAINS),
new BoundConstraint(new OAVAttributeType[]{OAVBDIRuntimeModel.plan_has_waitqueuewa, OAVBDIRuntimeModel.waitabstraction_has_messageeventtypes}, mpe, IOperator.CONTAINS),
}));
ObjectCondition aplconwc = new ObjectCondition(apl.getType());
aplconwc.addConstraint(new BoundConstraint(null, apl));
aplconwc.addConstraint(new BoundConstraint(OAVBDIRuntimeModel.apl_has_waitqueuecandidates, candwq, IOperator.CONTAINS));
ObjectCondition candconwc = new ObjectCondition(candwq.getType());
candconwc.addConstraint(new BoundConstraint(null, candwq));
candconwc.addConstraint(new BoundConstraint(OAVBDIRuntimeModel.waitqueuecandidate_has_plan, rplan));
// Rules for waitqueue candidates
Rule apl_add_waitqueuecand = new Rule("apl_add_waitqueuecand",
new AndCondition(new ICondition[]{
rpecon, capcon,
// new NotCondition(new AndCondition(new ICondition[]{wacon, planconwa})),
new NotCondition(planconwa),
// waconwq, planconwq,
planconwq,
new NotCondition(aplconwc)}),
ADD_WAITQUEUECAND_TO_APL);
Rule apl_make_available = new Rule("apl_make_available",
new AndCondition(new ICondition[]{
rpecon, capcon,
// new NotCondition(new AndCondition(new ICondition[]{wacon, planconwa,
new NotCondition(new AndCondition(new ICondition[]{planconwa,
new NotCondition(new AndCondition(new ICondition[]{candconpi, aplconpi})),
new NotCondition(new AndCondition(new ICondition[]{candconwc, aplconwc}))})),
// new NotCondition(new AndCondition(new ICondition[]{waconwq, planconwq,
new NotCondition(new AndCondition(new ICondition[]{planconwq,
new NotCondition(new AndCondition(new ICondition[]{candconpi, aplconpi})),
new NotCondition(new AndCondition(new ICondition[]{candconwc, aplconwc}))
}))}),
MAKE_APL_AVAILABLE);
return new Rule[]{apl_add_rplan, apl_add_waitqueuecand, apl_make_available};
}
//-------- APL Building finished rule --------
/**
*
*/
protected static void addMPlansToAPL(IOAVState state, Object rpe, Object rcapa)
{
Object mpe = state.getAttributeValue(rpe, OAVBDIRuntimeModel.element_has_model);
Object apl = state.getAttributeValue(rpe, OAVBDIRuntimeModel.processableelement_has_apl);
// Add mplans from precandidates
Object precandlist = state.getAttributeValue(rcapa, OAVBDIRuntimeModel.capability_has_precandidates, mpe);
if(precandlist!=null)
{
Collection precands = state.getAttributeValues(precandlist, OAVBDIRuntimeModel.precandidatelist_has_precandidates);
if(precands!=null)
{
for(Iterator it=precands.iterator(); it.hasNext(); )
{
Object precand = it.next();
Object mplan = state.getAttributeValue(precand, OAVBDIRuntimeModel.precandidate_has_mplan);
Object scope = state.getAttributeValue(precand, OAVBDIRuntimeModel.precandidate_has_capability);
Object triggerref = state.getAttributeValue(precand, OAVBDIRuntimeModel.precandidate_has_triggerreference);
Object mexp = state.getAttributeValue(triggerref, OAVBDIMetaModel.triggerreference_has_match);
OAVBDIFetcher fetcher = new OAVBDIFetcher(state, scope);
if(OAVBDIRuntimeModel.goal_type.equals(state.getType(rpe)))
fetcher.setRGoal(rpe);
else if(OAVBDIRuntimeModel.internalevent_type.equals(state.getType(rpe)))
fetcher.setRInternalEvent(rpe);
else if(OAVBDIRuntimeModel.messageevent_type.equals(state.getType(rpe)))
fetcher.setRMessageEvent(rpe);
boolean match = true;
if(mexp!=null)
{
try
{
match = ((Boolean)AgentRules.evaluateExpression(state, mexp, fetcher)).booleanValue();
}
catch(Exception e)
{
e.printStackTrace();
match = false;
}
}
if(match)
createMPlanCandidates(state, rpe, scope, apl, mplan, fetcher);
}
}
}
// When no candidates, remove apl as required by other rules (hack???)
Collection plancands = state.getAttributeValues(apl, OAVBDIRuntimeModel.apl_has_plancandidates);
Collection pinscands = state.getAttributeValues(apl, OAVBDIRuntimeModel.apl_has_planinstancecandidates);
Collection waitcands = state.getAttributeValues(apl, OAVBDIRuntimeModel.apl_has_waitqueuecandidates);
if((plancands==null || plancands.isEmpty())
&& (pinscands==null || pinscands.isEmpty())
&& (waitcands==null || waitcands.isEmpty()))
{
state.setAttributeValue(rpe, OAVBDIRuntimeModel.processableelement_has_apl, null);
state.setAttributeValue(rpe, OAVBDIRuntimeModel.processableelement_has_state,
OAVBDIRuntimeModel.PROCESSABLEELEMENT_NOCANDIDATES);
// When no candidates found, event processing stops here.
// state.setAttributeValue(ragent, OAVBDIRuntimeModel.agent_has_eventprocessing, null);
if(!state.getType(rpe).isSubtype(OAVBDIRuntimeModel.goal_type)
|| state.getAttributeValues(rpe, OAVBDIRuntimeModel.goal_has_triedmplans)==null)
{
BDIInterpreter ip = BDIInterpreter.getInterpreter(state);
ip.getLogger(rcapa).warning("Warning: Event/goal not handled: "+ip.getAgentAdapter().getComponentIdentifier().getLocalName()+rpe+" "
+state.getAttributeValue(state.getAttributeValue(rpe, OAVBDIRuntimeModel.element_has_model), OAVBDIMetaModel.modelelement_has_name));
// Remove unprocessable event from agent.
if(state.getType(rpe).isSubtype(OAVBDIRuntimeModel.internalevent_type))
{
state.removeAttributeValue(rcapa, OAVBDIRuntimeModel.capability_has_internalevents, rpe);
}
else if(state.getType(rpe).isSubtype(OAVBDIRuntimeModel.messageevent_type))
{
state.removeAttributeValue(rcapa, OAVBDIRuntimeModel.capability_has_messageevents, rpe);
}
}
}
else
{
state.setAttributeValue(rpe, OAVBDIRuntimeModel.processableelement_has_state,
OAVBDIRuntimeModel.PROCESSABLEELEMENT_APLAVAILABLE);
// System.out.println("APL available: "+rpe);
}
}
//-------- rule methods --------
/**
* Create the metalevel reasoning for goal rule.
*/
protected static Rule createMetaLevelReasoningForGoalRule()
{
Variable mmetagoal = new Variable("?mmetagoal", OAVBDIMetaModel.metagoal_type);
Variable mgoaltrigger = new Variable("?mgoaltrigger", OAVBDIMetaModel.metagoaltrigger_type);
Variable mcapa = new Variable("?mcapa", OAVBDIMetaModel.capability_type);
Variable rcapa = new Variable("?rcapa", OAVBDIRuntimeModel.capability_type);
Variable rpe = new Variable("?rpe", OAVBDIRuntimeModel.processableelement_type);
Variable mpe = new Variable("?mpe", OAVBDIMetaModel.processableelement_type);
Variable rtargetcapa = new Variable("?rtargetcapa", OAVBDIRuntimeModel.capability_type);
Variable triggerrefs = new Variable("?triggerrefs", OAVBDIMetaModel.triggerreference_type, true, false);
Variable ref = new Variable("?ref", OAVJavaType.java_string_type);
// There is a ?mmetagoal with a trigger (?mgoaltrigger)
ObjectCondition metagoalcon = new ObjectCondition(OAVBDIMetaModel.metagoal_type);
metagoalcon.addConstraint(new BoundConstraint(null, mmetagoal));
metagoalcon.addConstraint(new BoundConstraint(OAVBDIMetaModel.metagoal_has_trigger, mgoaltrigger));
// The ?mmetagoal is in a capability (?mcapa)
ObjectCondition mcapacon = new ObjectCondition(OAVBDIMetaModel.capability_type);
mcapacon.addConstraint(new BoundConstraint(null, mcapa));
mcapacon.addConstraint(new BoundConstraint(OAVBDIMetaModel.capability_has_goals,
mmetagoal, IOperator.CONTAINS));
// The ?mcapa has an instance (?rcapa)
ObjectCondition capacon = new ObjectCondition(OAVBDIRuntimeModel.capability_type);
capacon.addConstraint(new BoundConstraint(null, rcapa));
capacon.addConstraint(new BoundConstraint(OAVBDIRuntimeModel.element_has_model, mcapa));
// There is a processable element (?rpe) that needs processing
ObjectCondition pecon = new ObjectCondition(OAVBDIRuntimeModel.processableelement_type);
pecon.addConstraint(new BoundConstraint(null, rpe));
pecon.addConstraint(new LiteralConstraint(OAVBDIRuntimeModel.processableelement_has_state,
OAVBDIRuntimeModel.PROCESSABLEELEMENT_APLAVAILABLE));
pecon.addConstraint(new BoundConstraint(OAVBDIRuntimeModel.element_has_model, mpe));
// The ?rpe is in a capability (?rtargetcapa)
ObjectCondition targetcapacon = new ObjectCondition(OAVBDIRuntimeModel.capability_type);
targetcapacon.addConstraint(new BoundConstraint(null, rtargetcapa));
targetcapacon.addConstraint(new BoundConstraint(OAVBDIRuntimeModel.capability_has_goals,
rpe, IOperator.CONTAINS));
// The ?triggerref belongs to the metagoal trigger.
ObjectCondition metagoaltriggercon = new ObjectCondition(OAVBDIMetaModel.metagoaltrigger_type);
metagoaltriggercon.addConstraint(new BoundConstraint(null, mgoaltrigger));
metagoaltriggercon.addConstraint(new BoundConstraint(OAVBDIMetaModel.metagoaltrigger_has_goals, triggerrefs));
// There is a trigger reference (?triggerref) that maps to the ?rpe.
ObjectCondition trcon = new ObjectCondition(OAVBDIMetaModel.triggerreference_type);
trcon.addConstraint(new BoundConstraint(null, triggerrefs, IOperator.CONTAINS));
trcon.addConstraint(new BoundConstraint(OAVBDIMetaModel.triggerreference_has_ref, ref));
trcon.addConstraint(new LiteralReturnValueConstraint(Boolean.TRUE, new FunctionCall(new ResolvesTo(), new Object[]{rcapa, ref, rpe, rtargetcapa})));
Rule metalevel_reasoning = new Rule("metalevel_reasoning_for_goal",
new AndCondition(new ICondition[]{metagoalcon, mcapacon, capacon, pecon, targetcapacon, metagoaltriggercon, trcon}), METALEVEL_ACTION);
return metalevel_reasoning;
}
/**
* Create the metalevel reasoning for internal event rule.
*/
protected static Rule createMetaLevelReasoningForInternalEventRule()
{
Variable mmetagoal = new Variable("?mmetagoal", OAVBDIMetaModel.metagoal_type);
Variable mgoaltrigger = new Variable("?mgoaltrigger", OAVBDIMetaModel.metagoaltrigger_type);
Variable mcapa = new Variable("?mcapa", OAVBDIMetaModel.capability_type);
Variable rcapa = new Variable("?rcapa", OAVBDIRuntimeModel.capability_type);
Variable rpe = new Variable("?rpe", OAVBDIRuntimeModel.processableelement_type);
Variable mpe = new Variable("?mpe", OAVBDIMetaModel.processableelement_type);
Variable rtargetcapa = new Variable("?rtargetcapa", OAVBDIRuntimeModel.capability_type);
Variable triggerrefs = new Variable("?triggerrefs", OAVBDIMetaModel.triggerreference_type, true, false);
Variable ref = new Variable("?ref", OAVJavaType.java_string_type);
// There is a ?mmetagoal with a trigger (?mgoaltrigger)
ObjectCondition metagoalcon = new ObjectCondition(OAVBDIMetaModel.metagoal_type);
metagoalcon.addConstraint(new BoundConstraint(null, mmetagoal));
metagoalcon.addConstraint(new BoundConstraint(OAVBDIMetaModel.metagoal_has_trigger, mgoaltrigger));
// The ?mmetagoal is in a capability (?mcapa)
ObjectCondition mcapacon = new ObjectCondition(OAVBDIMetaModel.capability_type);
mcapacon.addConstraint(new BoundConstraint(null, mcapa));
mcapacon.addConstraint(new BoundConstraint(OAVBDIMetaModel.capability_has_goals,
mmetagoal, IOperator.CONTAINS));
// The ?mcapa has an instance (?rcapa)
ObjectCondition capacon = new ObjectCondition(OAVBDIRuntimeModel.capability_type);
capacon.addConstraint(new BoundConstraint(null, rcapa));
capacon.addConstraint(new BoundConstraint(OAVBDIRuntimeModel.element_has_model, mcapa));
// There is a processable element (?rpe) that needs processing
ObjectCondition pecon = new ObjectCondition(OAVBDIRuntimeModel.processableelement_type);
pecon.addConstraint(new BoundConstraint(null, rpe));
pecon.addConstraint(new LiteralConstraint(OAVBDIRuntimeModel.processableelement_has_state,
OAVBDIRuntimeModel.PROCESSABLEELEMENT_APLAVAILABLE));
pecon.addConstraint(new BoundConstraint(OAVBDIRuntimeModel.element_has_model, mpe));
// The ?rpe is in a capability (?rtargetcapa)
ObjectCondition targetcapacon = new ObjectCondition(OAVBDIRuntimeModel.capability_type);
targetcapacon.addConstraint(new BoundConstraint(null, rtargetcapa));
targetcapacon.addConstraint(new BoundConstraint(OAVBDIRuntimeModel.capability_has_internalevents,
rpe, IOperator.CONTAINS));
// The ?triggerref belongs to the metagoal trigger.
ObjectCondition metagoaltriggercon = new ObjectCondition(OAVBDIMetaModel.metagoaltrigger_type);
metagoaltriggercon.addConstraint(new BoundConstraint(null, mgoaltrigger));
metagoaltriggercon.addConstraint(new BoundConstraint(OAVBDIMetaModel.trigger_has_internalevents, triggerrefs));
// There is a trigger reference (?triggerref) that maps to the ?rpe.
ObjectCondition trcon = new ObjectCondition(OAVBDIMetaModel.triggerreference_type);
trcon.addConstraint(new BoundConstraint(null, triggerrefs, IOperator.CONTAINS));
trcon.addConstraint(new BoundConstraint(OAVBDIMetaModel.triggerreference_has_ref, ref));
trcon.addConstraint(new LiteralReturnValueConstraint(Boolean.TRUE, new FunctionCall(new ResolvesTo(), new Object[]{rcapa, ref, rpe, rtargetcapa})));
Rule metalevel_reasoning = new Rule("metalevel_reasoning_for_internalevent",
new AndCondition(new ICondition[]{metagoalcon, mcapacon, capacon, pecon, targetcapacon, metagoaltriggercon, trcon}), METALEVEL_ACTION);
return metalevel_reasoning;
}
/**
* Create the metalevel reasoning for message event rule.
*/
protected static Rule createMetaLevelReasoningForMessageEventRule()
{
Variable mmetagoal = new Variable("?mmetagoal", OAVBDIMetaModel.metagoal_type);
Variable mgoaltrigger = new Variable("?mgoaltrigger", OAVBDIMetaModel.metagoaltrigger_type);
Variable mcapa = new Variable("?mcapa", OAVBDIMetaModel.capability_type);
Variable rcapa = new Variable("?rcapa", OAVBDIRuntimeModel.capability_type);
Variable rpe = new Variable("?rpe", OAVBDIRuntimeModel.processableelement_type);
Variable mpe = new Variable("?mpe", OAVBDIMetaModel.processableelement_type);
Variable rtargetcapa = new Variable("?rtargetcapa", OAVBDIRuntimeModel.capability_type);
Variable triggerrefs = new Variable("?triggerrefs", OAVBDIMetaModel.triggerreference_type, true, false);
Variable ref = new Variable("?ref", OAVJavaType.java_string_type);
// There is a ?mmetagoal with a trigger (?mgoaltrigger)
ObjectCondition metagoalcon = new ObjectCondition(OAVBDIMetaModel.metagoal_type);
metagoalcon.addConstraint(new BoundConstraint(null, mmetagoal));
metagoalcon.addConstraint(new BoundConstraint(OAVBDIMetaModel.metagoal_has_trigger, mgoaltrigger));
// The ?mmetagoal is in a capability (?mcapa)
ObjectCondition mcapacon = new ObjectCondition(OAVBDIMetaModel.capability_type);
mcapacon.addConstraint(new BoundConstraint(null, mcapa));
mcapacon.addConstraint(new BoundConstraint(OAVBDIMetaModel.capability_has_goals,
mmetagoal, IOperator.CONTAINS));
// The ?mcapa has an instance (?rcapa)
ObjectCondition capacon = new ObjectCondition(OAVBDIRuntimeModel.capability_type);
capacon.addConstraint(new BoundConstraint(null, rcapa));
capacon.addConstraint(new BoundConstraint(OAVBDIRuntimeModel.element_has_model, mcapa));
// There is a processable element (?rpe) that needs processing
ObjectCondition pecon = new ObjectCondition(OAVBDIRuntimeModel.processableelement_type);
pecon.addConstraint(new BoundConstraint(null, rpe));
pecon.addConstraint(new LiteralConstraint(OAVBDIRuntimeModel.processableelement_has_state,
OAVBDIRuntimeModel.PROCESSABLEELEMENT_APLAVAILABLE));
pecon.addConstraint(new BoundConstraint(OAVBDIRuntimeModel.element_has_model, mpe));
// The ?rpe is in a capability (?rtargetcapa)
ObjectCondition targetcapacon = new ObjectCondition(OAVBDIRuntimeModel.capability_type);
targetcapacon.addConstraint(new BoundConstraint(null, rtargetcapa));
targetcapacon.addConstraint(new BoundConstraint(OAVBDIRuntimeModel.capability_has_messageevents,
rpe, IOperator.CONTAINS));
// The ?triggerref belongs to the metagoal trigger.
ObjectCondition metagoaltriggercon = new ObjectCondition(OAVBDIMetaModel.metagoaltrigger_type);
metagoaltriggercon.addConstraint(new BoundConstraint(null, mgoaltrigger));
metagoaltriggercon.addConstraint(new BoundConstraint(OAVBDIMetaModel.trigger_has_messageevents, triggerrefs));
// There is a trigger reference (?triggerref) that maps to the ?rpe.
ObjectCondition trcon = new ObjectCondition(OAVBDIMetaModel.triggerreference_type);
trcon.addConstraint(new BoundConstraint(null, triggerrefs, IOperator.CONTAINS));
trcon.addConstraint(new BoundConstraint(OAVBDIMetaModel.triggerreference_has_ref, ref));
trcon.addConstraint(new LiteralReturnValueConstraint(Boolean.TRUE, new FunctionCall(new ResolvesTo(), new Object[]{rcapa, ref, rpe, rtargetcapa})));
Rule metalevel_reasoning = new Rule("metalevel_reasoning_for_messageevent",
new AndCondition(new ICondition[]{metagoalcon, mcapacon, capacon, pecon, targetcapacon, metagoaltriggercon, trcon}), METALEVEL_ACTION);
return metalevel_reasoning;
}
protected static IAction METALEVEL_ACTION = new IAction()
{
public void execute(IOAVState state, IVariableAssignments assignments)
{
// System.out.println("Meta-level reasoning started.");
Object rpe = assignments.getVariableValue("?rpe");
Object rcapa = assignments.getVariableValue("?rcapa");
// Object ragent = assignments.getVariableValue("?ragent");
Object mmetagoal = assignments.getVariableValue("?mmetagoal");
String type = (String)state.getAttributeValue(mmetagoal, OAVBDIMetaModel.modelelement_has_name);
Object rmetagoal = GoalLifecycleRules.createGoal(state, rcapa, type);
String appname = "applicables";
Object appparamset = state.getAttributeValue(rmetagoal, OAVBDIRuntimeModel.parameterelement_has_parametersets, appname);
// Todo: create parameter in runtime if not declared in model.
// if(appparamset==null)
// {
// Object mapp = state.getAttributeValue(mmetagoal, OAVBDIMetaModel.parameterelement_has_parameters, appname);
// Class clazz = (Class)state.getAttributeValue(mapp, OAVBDIMetaModel.typedelement_has_class);
// appparamset = BeliefRules.createParameterSet(state, appname, null, clazz, rmetagoal, null, rcapa);
// }
// Hack! Create result paramset for making querygoal valid :-(
// String resultname = "result";
// Object resultparamset = state.getAttributeValue(rmetagoal, OAVBDIRuntimeModel.parameterelement_has_parametersets, resultname);
// Todo: create parameter in runtime if not declared in model.
// if(resultparamset==null)
// {
// Object res = state.getAttributeValue(mmetagoal, OAVBDIMetaModel.parameterelement_has_parameters, resultname);
// Class clazz = (Class)state.getAttributeValue(res, OAVBDIMetaModel.typedelement_has_class);
// appparamset = BeliefRules.createParameterSet(state, resultname, null, clazz, rmetagoal, null, rcapa);
// }
// Extract candidates from apl and add them all to the parameterset "applicables"
Object apl = state.getAttributeValue(rpe, OAVBDIRuntimeModel.processableelement_has_apl);
Collection rcands = state.getAttributeValues(apl, OAVBDIRuntimeModel.apl_has_planinstancecandidates);
if(rcands!=null)
{
for(Iterator it=rcands.iterator(); it.hasNext(); )
{
Object rplancand = it.next();
Object rplan = state.getAttributeValue(rplancand, OAVBDIRuntimeModel.plancandidate_has_plan);
Object rscope = state.getAttributeValue(rplancand, OAVBDIRuntimeModel.plancandidate_has_rcapa);
PlanInstanceInfoFlyweight piif = new PlanInstanceInfoFlyweight(state, rscope, rplan, rpe);
BeliefRules.addParameterSetValue(state, appparamset, piif);
}
}
Collection mcands = state.getAttributeValues(apl, OAVBDIRuntimeModel.apl_has_plancandidates);
if(mcands!=null)
{
for(Iterator it=mcands.iterator(); it.hasNext(); )
{
Object mplancand = it.next();
PlanInfoFlyweight pif = new PlanInfoFlyweight(state, rcapa, mplancand, rpe);
BeliefRules.addParameterSetValue(state, appparamset, pif);
}
}
// Adopt meta-level goal and let it select between applicables.
GoalLifecycleRules.adoptGoal(state, rcapa, rmetagoal);
state.setAttributeValue(apl, OAVBDIRuntimeModel.apl_has_metagoal, rmetagoal);
state.setAttributeValue(rpe, OAVBDIRuntimeModel.processableelement_has_state,
OAVBDIRuntimeModel.PROCESSABLEELEMENT_METALEVELREASONING);
// Set processing from original rpe to metagoal to allow buildAPL rule
// Will be reset to null, once a candidate is selected.
// state.setAttributeValue(ragent, OAVBDIRuntimeModel.agent_has_eventprocessing, rmetagoal);
}
};
/**
* Create the metalevel reasoning finished rule.
*/
protected static Rule createMetaLevelReasoningFinishedRule()
{
Variable mmetagoal = new Variable("?mmetagoal", OAVBDIMetaModel.metagoal_type);
Variable rmetagoal = new Variable("?rmetagoal", OAVBDIRuntimeModel.goal_type);
Variable rpe = new Variable("?rpe", OAVBDIRuntimeModel.processableelement_type);
Variable apl = new Variable("?apl", OAVBDIRuntimeModel.apl_type);
Variable rcapa = new Variable("?rcapa", OAVBDIRuntimeModel.capability_type);
// The type of the ?mgoal is metagoal
ObjectCondition mgoalcon = new ObjectCondition(OAVBDIMetaModel.metagoal_type);
mgoalcon.addConstraint(new BoundConstraint(null, mmetagoal));
// The ?rmetagoal belongs to the ?rmetagoal and it is finished (dropped)
ObjectCondition goalcon = new ObjectCondition(OAVBDIRuntimeModel.goal_type);
goalcon.addConstraint(new BoundConstraint(null, rmetagoal));
goalcon.addConstraint(new BoundConstraint(OAVBDIRuntimeModel.element_has_model, mmetagoal));
goalcon.addConstraint(new LiteralConstraint(OAVBDIRuntimeModel.goal_has_lifecyclestate, OAVBDIRuntimeModel.GOALLIFECYCLESTATE_DROPPED));
// An ?apl refers to the ?rmetagoal
ObjectCondition aplcon = new ObjectCondition(OAVBDIRuntimeModel.apl_type);
aplcon.addConstraint(new BoundConstraint(null, apl));
aplcon.addConstraint(new BoundConstraint(OAVBDIRuntimeModel.apl_has_metagoal, rmetagoal));
// There is an ?rpe (processable element) with the ?apl
ObjectCondition pecon = new ObjectCondition(OAVBDIRuntimeModel.processableelement_type);
pecon.addConstraint(new BoundConstraint(null, rpe));
pecon.addConstraint(new BoundConstraint(OAVBDIRuntimeModel.processableelement_has_apl, apl));
// The ?rpe (processable element) is contained in an ?rcapa
ObjectCondition capcon = new ObjectCondition(OAVBDIRuntimeModel.capability_type);
capcon.addConstraint(new BoundConstraint(null, rcapa));
capcon.addConstraint(new OrConstraint(new IConstraint[]{
new BoundConstraint(OAVBDIRuntimeModel.capability_has_internalevents, rpe, IOperator.CONTAINS),
new BoundConstraint(OAVBDIRuntimeModel.capability_has_messageevents, rpe, IOperator.CONTAINS),
new BoundConstraint(OAVBDIRuntimeModel.capability_has_goals, rpe, IOperator.CONTAINS)
}));
IAction action = new IAction()
{
public void execute(IOAVState state, IVariableAssignments assignments)
{
// System.out.println("Meta-level reasoning finished.");
Object rmetagoal = assignments.getVariableValue("?rmetagoal");
Object rpe = assignments.getVariableValue("?rpe");
Object apl = assignments.getVariableValue("?apl");
Object rcapa = assignments.getVariableValue("?rcapa");
Object rparamsetresult = state.getAttributeValue(rmetagoal, OAVBDIRuntimeModel.parameterelement_has_parametersets, "result");
Collection result = state.getAttributeValues(rparamsetresult, OAVBDIRuntimeModel.parameterset_has_values);
if(result==null)
{
state.setAttributeValue(rpe, OAVBDIRuntimeModel.processableelement_has_state,
OAVBDIRuntimeModel.PROCESSABLEELEMENT_NOCANDIDATES);
BDIInterpreter.getInterpreter(state).getLogger(rcapa).severe("Meta-level reasoning did not return a result.");
}
else
{
for(Iterator it=result.iterator(); it.hasNext(); )
{
ICandidateInfo ci = (ICandidateInfo)it.next();
Object rplan = ((PlanFlyweight)ci.getPlan()).getHandle();
PlanRules.adoptPlan(state, rcapa, rplan);
if(ci instanceof PlanInfoFlyweight)
{
// Save candidate in plan for later apl removal and exclude list management.
if(state.getType(rpe).isSubtype(OAVBDIRuntimeModel.goal_type))
state.setAttributeValue(rplan, OAVBDIRuntimeModel.plan_has_plancandidate, ((PlanInfoFlyweight)ci).getHandle());
}
else if(ci instanceof PlanInstanceInfoFlyweight)
{
// Save candidate in plan for later apl removal and exclude list management.
if(state.getType(rpe).isSubtype(OAVBDIRuntimeModel.goal_type))
{
Object plan = ((PlanInstanceInfoFlyweight)ci).getHandle();
state.setAttributeValue(plan, OAVBDIRuntimeModel.plan_has_planinstancecandidate, plan);
}
}
// boolean isgoal = state.getType(rpe).isSubtype(OAVBDIRuntimeModel.goal_type);
// if(isgoal)
// {
// Object candidate = ((ElementFlyweight)ci).getHandle();
// removeAPLCandidate(state, rpe, candidate);
// }
}
state.setAttributeValue(apl, OAVBDIRuntimeModel.apl_has_metagoal, null);
state.setAttributeValue(rpe, OAVBDIRuntimeModel.processableelement_has_state,
OAVBDIRuntimeModel.PROCESSABLEELEMENT_CANDIDATESSELECTED);
// Collection mpcs = state.getAttributeValues(apl, OAVBDIRuntimeModel.apl_has_plancandidates);
// Collection pics = state.getAttributeValues(apl, OAVBDIRuntimeModel.apl_has_planinstancecandidates);
// Collection wqcs = state.getAttributeValues(apl, OAVBDIRuntimeModel.apl_has_waitqueuecandidates);
// if(mpcs==null && pics==null && wqcs==null)
// state.setAttributeValue(rpe, OAVBDIRuntimeModel.processableelement_has_apl, null);
}
}
};
Rule metalevel_reasoning_fini = new Rule("metalevel_reasoning_finished",
new AndCondition(new ICondition[]{mgoalcon, goalcon, aplcon, pecon, capcon}), action);
return metalevel_reasoning_fini;
}
/**
* Create the select candidates for goal rule.
*/
protected static Rule createSelectCandidatesForGoalRule()
{
Variable rpe = new Variable("?rpe", OAVBDIRuntimeModel.processableelement_type);
Variable mpe = new Variable("?mpe", OAVBDIMetaModel.processableelement_type);
Variable rcapa = new Variable("?rcapa", OAVBDIRuntimeModel.capability_type);
Variable mmetagoal = new Variable("?mmetagoal", OAVBDIMetaModel.metagoal_type);
Variable mgoaltrigger = new Variable("?mgoaltrigger", OAVBDIMetaModel.metagoaltrigger_type);
Variable ragent = new Variable("?ragent", OAVBDIRuntimeModel.agent_type);
// Todo: Should trigger separately for each plan?
ObjectCondition rpecon = new ObjectCondition(OAVBDIRuntimeModel.processableelement_type);
rpecon.addConstraint(new BoundConstraint(null, rpe));
rpecon.addConstraint(new LiteralConstraint(OAVBDIRuntimeModel.processableelement_has_state,
OAVBDIRuntimeModel.PROCESSABLEELEMENT_APLAVAILABLE));
rpecon.addConstraint(new BoundConstraint(OAVBDIRuntimeModel.element_has_model, mpe));
ObjectCondition capcon = new ObjectCondition(OAVBDIRuntimeModel.capability_type);
capcon.addConstraint(new BoundConstraint(null, rcapa));
// Specific part
capcon.addConstraint(new BoundConstraint(OAVBDIRuntimeModel.capability_has_goals,
rpe, IOperator.CONTAINS));
ObjectCondition agentcon = new ObjectCondition(ragent.getType());
agentcon.addConstraint(new BoundConstraint(null, ragent));
ObjectCondition metagoalcon = new ObjectCondition(OAVBDIMetaModel.metagoal_type);
metagoalcon.addConstraint(new BoundConstraint(null, mmetagoal));
metagoalcon.addConstraint(new BoundConstraint(OAVBDIMetaModel.metagoal_has_trigger, mgoaltrigger));
ObjectCondition metagoaltriggercon = new ObjectCondition(OAVBDIMetaModel.metagoaltrigger_type);
metagoaltriggercon.addConstraint(new BoundConstraint(null, mgoaltrigger));
metagoaltriggercon.addConstraint(new BoundConstraint(OAVBDIMetaModel.metagoaltrigger_has_goals,
mpe, IOperator.CONTAINS));
NotCondition nometacon = new NotCondition(new AndCondition(
new ICondition[]{metagoalcon, metagoaltriggercon}));
IAction action = new IAction()
{
public void execute(IOAVState state, IVariableAssignments assignments)
{
Object rpe = assignments.getVariableValue("?rpe");
Object apl = state.getAttributeValue(rpe, OAVBDIRuntimeModel.processableelement_has_apl);
Object mpe = state.getAttributeValue(rpe, OAVBDIRuntimeModel.element_has_model);
// System.out.println("scfg: "+state.getAttributeValue(rpe, OAVBDIRuntimeModel.processableelement_has_state));
// Find best candidates
List cands = reason(state, rpe, apl);
// System.out.println("createSelectCandidatesForGoalRule: schedulePlanInstance: "
// +BDIInterpreter.getInterpreter(state).getAgentAdapter().getComponentIdentifier().getLocalName());
// Check if candidates are still valid.
// Uses optimistic scheme, i.e. apl may hold invalid entries.
// Then the process must be started over again.
Object cand = checkCandidates(state, rpe, apl, cands);
if(cand!=null)
{
// System.out.println("Check candidates failed: "+cand+", "+rpe+", "+BDIInterpreter.getInterpreter(state).getAgentAdapter().getComponentIdentifier().getLocalName());
state.setAttributeValue(rpe, OAVBDIRuntimeModel.processableelement_has_state, OAVBDIRuntimeModel.PROCESSABLEELEMENT_UNPROCESSED);
boolean rebuild = ((Boolean)state.getAttributeValue(mpe, OAVBDIMetaModel.goal_has_rebuild)).booleanValue();
if(rebuild)
{
state.getAttributeValue(rpe, OAVBDIRuntimeModel.processableelement_has_apl, null);
}
else
{
// Remove plan candidate from apl.
if(state.getType(cand).equals(OAVBDIRuntimeModel.waitqueuecandidate_type))
state.removeAttributeValue(apl, OAVBDIRuntimeModel.apl_has_waitqueuecandidates, cand);
else
state.removeAttributeValue(apl, OAVBDIRuntimeModel.apl_has_planinstancecandidates, cand);
}
}
else
{
// Create resp. activate plan(instances)
scheduleCandidates(state, rpe, apl, cands);
// Remove candidates from apl if not rebuild
boolean rebuild = ((Boolean)state.getAttributeValue(mpe, OAVBDIMetaModel.goal_has_rebuild)).booleanValue();
boolean retry = ((Boolean)state.getAttributeValue(mpe, OAVBDIMetaModel.goal_has_retry)).booleanValue();
// if(!rebuild)
// {
// for(int i=0; i<cands.size(); i++)
// removeAPLCandidate(state, rpe, cands.get(i));
//
// // Clear apl if empty
// Collection pcs = state.getAttributeValues(apl, OAVBDIRuntimeModel.apl_has_plancandidates);
// Collection pics = state.getAttributeValues(apl, OAVBDIRuntimeModel.apl_has_planinstancecandidates);
// Collection wqcs = state.getAttributeValues(apl, OAVBDIRuntimeModel.apl_has_waitqueuecandidates);
// if(pcs==null && pics==null && wqcs==null)
// {
//// System.out.println("Set null apl: "+rpe+" "+apl);
// state.setAttributeValue(rpe, OAVBDIRuntimeModel.processableelement_has_apl, null);
// }
// }
// If always rebuild or not retry clear apl.
if(rebuild || !retry)
{
state.setAttributeValue(rpe, OAVBDIRuntimeModel.processableelement_has_apl, null);
}
// Reset inprocess flag.
// state.setAttributeValue(ragent, OAVBDIRuntimeModel.agent_has_eventprocessing, null);
}
}
};
Rule rule = new Rule("candidates_select_for_goal",
new AndCondition(new ICondition[]{rpecon, capcon, nometacon, agentcon}), action);
return rule;
}
/**
* Create the select candidates for internal event rule.
*/
protected static Rule createSelectCandidatesForInternalEventRule()
{
Variable rpe = new Variable("?rpe", OAVBDIRuntimeModel.processableelement_type);
Variable mpe = new Variable("?mpe", OAVBDIMetaModel.processableelement_type);
Variable rcapa = new Variable("?rcapa", OAVBDIRuntimeModel.capability_type);
Variable mmetagoal = new Variable("?mmetagoal", OAVBDIMetaModel.metagoal_type);
Variable mgoaltrigger = new Variable("?mgoaltrigger", OAVBDIMetaModel.metagoaltrigger_type);
Variable ragent = new Variable("?ragent", OAVBDIRuntimeModel.agent_type);
// Todo: Should trigger separately for each plan?
ObjectCondition rpecon = new ObjectCondition(OAVBDIRuntimeModel.processableelement_type);
rpecon.addConstraint(new BoundConstraint(null, rpe));
rpecon.addConstraint(new LiteralConstraint(OAVBDIRuntimeModel.processableelement_has_state,
OAVBDIRuntimeModel.PROCESSABLEELEMENT_APLAVAILABLE));
rpecon.addConstraint(new BoundConstraint(OAVBDIRuntimeModel.element_has_model, mpe));
ObjectCondition capcon = new ObjectCondition(OAVBDIRuntimeModel.capability_type);
capcon.addConstraint(new BoundConstraint(null, rcapa));
// Specific part
capcon.addConstraint(new BoundConstraint(OAVBDIRuntimeModel.capability_has_internalevents,
rpe, IOperator.CONTAINS));
ObjectCondition agentcon = new ObjectCondition(ragent.getType());
agentcon.addConstraint(new BoundConstraint(null, ragent));
ObjectCondition metagoalcon = new ObjectCondition(OAVBDIMetaModel.metagoal_type);
metagoalcon.addConstraint(new BoundConstraint(null, mmetagoal));
metagoalcon.addConstraint(new BoundConstraint(OAVBDIMetaModel.metagoal_has_trigger, mgoaltrigger));
// Todo: reasoning across scopes
ObjectCondition metagoaltriggercon = new ObjectCondition(OAVBDIMetaModel.metagoaltrigger_type);
metagoaltriggercon.addConstraint(new BoundConstraint(null, mgoaltrigger));
metagoaltriggercon.addConstraint(new BoundConstraint(OAVBDIMetaModel.trigger_has_internalevents,
mpe, IOperator.CONTAINS));
NotCondition nometacon = new NotCondition(new AndCondition(
new ICondition[]{metagoalcon, metagoaltriggercon}));
IAction action = new IAction()
{
public void execute(IOAVState state, IVariableAssignments assignments)
{
Object rpe = assignments.getVariableValue("?rpe");
Object rcapa = assignments.getVariableValue("?rcapa");
// Object ragent = assignments.getVariableValue("?ragent");
Object apl = state.getAttributeValue(rpe, OAVBDIRuntimeModel.processableelement_has_apl);
// Find best candidates
List cands = reason(state, rpe, apl);
// System.out.println("createSelectCandidatesForInternalEventRule: schedulePlanInstance: "
// +BDIInterpreter.getInterpreter(state).getAgentAdapter().getComponentIdentifier().getLocalName());
// Check if candidates are still valid.
// Uses optimistic scheme, i.e. apl may hold invalid entries.
// Then the process must be started over again.
// Object mpe = state.getAttributeValue(rpe, OAVBDIRuntimeModel.element_has_model);
Object cand = checkCandidates(state, rpe, apl, cands);
if(cand!=null)
{
// System.out.println("Check candidates failed: "+cand+", "+rpe+", "+BDIInterpreter.getInterpreter(state).getAgentAdapter().getComponentIdentifier().getLocalName());
state.setAttributeValue(rpe, OAVBDIRuntimeModel.processableelement_has_state, OAVBDIRuntimeModel.PROCESSABLEELEMENT_UNPROCESSED);
state.setAttributeValue(rpe, OAVBDIRuntimeModel.processableelement_has_apl, null);
}
else
{
// Create resp. activate plan(instances)
scheduleCandidates(state, rpe, apl, cands);
// Clear apl if empty
Collection pcs = state.getAttributeValues(apl, OAVBDIRuntimeModel.apl_has_plancandidates);
Collection pics = state.getAttributeValues(apl, OAVBDIRuntimeModel.apl_has_planinstancecandidates);
Collection wqcs = state.getAttributeValues(apl, OAVBDIRuntimeModel.apl_has_waitqueuecandidates);
if(pcs==null && pics==null && wqcs==null)
state.setAttributeValue(rpe, OAVBDIRuntimeModel.processableelement_has_apl, null);
// Reset inprocess flag.
// state.setAttributeValue(ragent, OAVBDIRuntimeModel.agent_has_eventprocessing, null);
// Remove rpe if internal event
state.removeAttributeValue(rcapa, OAVBDIRuntimeModel.capability_has_internalevents, rpe);
}
}
};
Rule rule = new Rule("candidates_select_for_internalevent",
new AndCondition(new ICondition[]{rpecon, capcon, nometacon, agentcon}), action);
return rule;
}
/**
* Create the select candidates for message event rule.
*/
protected static Rule createSelectCandidatesForMessageEventRule()
{
Variable rpe = new Variable("?rpe", OAVBDIRuntimeModel.processableelement_type);
Variable mpe = new Variable("?mpe", OAVBDIMetaModel.processableelement_type);
Variable rcapa = new Variable("?rcapa", OAVBDIRuntimeModel.capability_type);
Variable mmetagoal = new Variable("?mmetagoal", OAVBDIMetaModel.metagoal_type);
Variable mgoaltrigger = new Variable("?mgoaltrigger", OAVBDIMetaModel.metagoaltrigger_type);
Variable ragent = new Variable("?ragent", OAVBDIRuntimeModel.agent_type);
// Todo: Should trigger separately for each plan?
ObjectCondition rpecon = new ObjectCondition(OAVBDIRuntimeModel.processableelement_type);
rpecon.addConstraint(new BoundConstraint(null, rpe));
rpecon.addConstraint(new LiteralConstraint(OAVBDIRuntimeModel.processableelement_has_state,
OAVBDIRuntimeModel.PROCESSABLEELEMENT_APLAVAILABLE));
rpecon.addConstraint(new BoundConstraint(OAVBDIRuntimeModel.element_has_model, mpe));
ObjectCondition capcon = new ObjectCondition(OAVBDIRuntimeModel.capability_type);
capcon.addConstraint(new BoundConstraint(null, rcapa));
// Specific part
capcon.addConstraint(new BoundConstraint(OAVBDIRuntimeModel.capability_has_messageevents,
rpe, IOperator.CONTAINS));
ObjectCondition agentcon = new ObjectCondition(ragent.getType());
agentcon.addConstraint(new BoundConstraint(null, ragent));
ObjectCondition metagoalcon = new ObjectCondition(OAVBDIMetaModel.metagoal_type);
metagoalcon.addConstraint(new BoundConstraint(null, mmetagoal));
metagoalcon.addConstraint(new BoundConstraint(OAVBDIMetaModel.metagoal_has_trigger, mgoaltrigger));
ObjectCondition metagoaltriggercon = new ObjectCondition(OAVBDIMetaModel.metagoaltrigger_type);
metagoaltriggercon.addConstraint(new BoundConstraint(null, mgoaltrigger));
metagoaltriggercon.addConstraint(new BoundConstraint(OAVBDIMetaModel.trigger_has_messageevents,
mpe, IOperator.CONTAINS));
NotCondition nometacon = new NotCondition(new AndCondition(
new ICondition[]{metagoalcon, metagoaltriggercon}));
IAction action = new IAction()
{
public void execute(IOAVState state, IVariableAssignments assignments)
{
Object rpe = assignments.getVariableValue("?rpe");
Object rcapa = assignments.getVariableValue("?rcapa");
// Object ragent = assignments.getVariableValue("?ragent");
Object apl = state.getAttributeValue(rpe, OAVBDIRuntimeModel.processableelement_has_apl);
// Find best candidates
List cands = reason(state, rpe, apl);
// System.out.println("createSelectCandidatesForMessageEventRule: schedulePlanInstance: "
// +BDIInterpreter.getInterpreter(state).getAgentAdapter().getComponentIdentifier().getLocalName());
// Check if candidates are still valid.
// Uses optimistic scheme, i.e. apl may hold invalid entries.
// Then the process must be started over again.
// Object mpe = state.getAttributeValue(rpe, OAVBDIRuntimeModel.element_has_model);
Object cand = checkCandidates(state, rpe, apl, cands);
if(cand!=null)
{
// System.out.println("Check candidates failed: "+cand+", "+rpe+", "+BDIInterpreter.getInterpreter(state).getAgentAdapter().getComponentIdentifier().getLocalName());
state.setAttributeValue(rpe, OAVBDIRuntimeModel.processableelement_has_state, OAVBDIRuntimeModel.PROCESSABLEELEMENT_UNPROCESSED);
state.setAttributeValue(rpe, OAVBDIRuntimeModel.processableelement_has_apl, null);
}
else
{
// Create resp. activate plan(instances)
scheduleCandidates(state, rpe, apl, cands);
// Clear apl if empty
Collection pcs = state.getAttributeValues(apl, OAVBDIRuntimeModel.apl_has_plancandidates);
Collection pics = state.getAttributeValues(apl, OAVBDIRuntimeModel.apl_has_planinstancecandidates);
Collection wqcs = state.getAttributeValues(apl, OAVBDIRuntimeModel.apl_has_waitqueuecandidates);
if(pcs==null && pics==null && wqcs==null)
{
// System.out.println("Set null apl: "+rpe+" "+apl);
state.setAttributeValue(rpe, OAVBDIRuntimeModel.processableelement_has_apl, null);
}
// Reset inprocess flag.
// state.setAttributeValue(ragent, OAVBDIRuntimeModel.agent_has_eventprocessing, null);
// Remove rpe if message or internal event
state.removeAttributeValue(rcapa, OAVBDIRuntimeModel.capability_has_messageevents, rpe);
}
}
};
Rule rule = new Rule("candidates_select_for_messageevent",
new AndCondition(new ICondition[]{rpecon, capcon, nometacon, agentcon}), action);
return rule;
}
/*protected static IAction SELECT_CANDIDATE_ACTION = new IAction()
{
public void execute(IOAVState state, IVariableAssignments assignments)
{
Object rpe = assignments.getVariableValue("?rpe");
Object rcapa = assignments.getVariableValue("?rcapa");
Object apl = state.getAttributeValue(rpe, OAVBDIRuntimeModel.processableelement_has_apl);
OAVObjectType otype = state.getType(rpe);
// Find best candidates
List cands = reason(state, rpe, apl);
// Create resp. activate plan(instances)
scheduleCandidates(state, rcapa, rpe, apl, cands);
// Remove candidates from apl if goal type
if(OAVBDIMetaModel.goal_type.isSubtype(otype))
{
for(int i=0; i<cands.size(); i++)
removeAPLCandidate(state, rpe, cands.get(i));
}
// Clear apl if empty
Collection pcs = state.getAttributeValues(apl, OAVBDIRuntimeModel.apl_has_plancandidates);
Collection pics = state.getAttributeValues(apl, OAVBDIRuntimeModel.apl_has_planinstancecandidates);
Collection wqcs = state.getAttributeValues(apl, OAVBDIRuntimeModel.apl_has_waitqueuecandidates);
if(pcs==null && pics==null && wqcs==null)
state.setAttributeValue(rpe, OAVBDIRuntimeModel.processableelement_has_apl, null);
// Reset inprocess flag.
state.setAttributeValue(rcapa, OAVBDIRuntimeModel.capability_has_eventprocessing, null);
// Remove rpe if message or internal event
if(OAVBDIMetaModel.messageevent_type.equals(otype))
state.removeAttributeValue(rcapa, OAVBDIRuntimeModel.capability_has_messageevents, rpe);
else if(OAVBDIMetaModel.internalevent_type.equals(otype))
state.removeAttributeValue(rcapa, OAVBDIRuntimeModel.capability_has_internalevents, rpe);
}
};*/
/**
* Create dispatch message event from waitqueue rule.
*/
protected static Rule createDispatchMessageEventFromWaitqueueRule()
{
Variable rpe = new Variable("?rpe", OAVBDIRuntimeModel.messageevent_type);
Variable orig = new Variable("?orig", OAVBDIRuntimeModel.messageevent_type);
Variable mpe = new Variable("?mpe", OAVBDIMetaModel.messageevent_type);
Variable rplan = new Variable("?rplan", OAVBDIRuntimeModel.plan_type);
// Variable wa = new Variable("?wa", OAVBDIRuntimeModel.waitabstraction_type);
Variable rcapa = new Variable("?rcapa", OAVBDIRuntimeModel.capability_type);
// Variable ragent = new Variable("?ragent", OAVBDIRuntimeModel.agent_type);
ObjectCondition rpecon = new ObjectCondition(OAVBDIRuntimeModel.messageevent_type);
rpecon.addConstraint(new BoundConstraint(null, rpe));
rpecon.addConstraint(new BoundConstraint(OAVBDIRuntimeModel.element_has_model, mpe));
rpecon.addConstraint(new BoundConstraint(OAVBDIRuntimeModel.messageevent_has_original, orig));
ObjectCondition plancon = new ObjectCondition(OAVBDIRuntimeModel.plan_type);
plancon.addConstraint(new BoundConstraint(null, rplan));
plancon.addConstraint(new LiteralConstraint(OAVBDIRuntimeModel.plan_has_processingstate,
OAVBDIRuntimeModel.PLANPROCESSINGTATE_WAITING));
plancon.addConstraint(new BoundConstraint(OAVBDIRuntimeModel.plan_has_waitqueueelements,
rpe, IOperator.CONTAINS));
// plancon.addConstraint(new BoundConstraint(OAVBDIRuntimeModel.plan_has_waitabstraction, wa));
plancon.addConstraint(new OrConstraint(new IConstraint[]
{
new BoundConstraint(new OAVAttributeType[]{OAVBDIRuntimeModel.plan_has_waitabstraction, OAVBDIRuntimeModel.waitabstraction_has_messageeventtypes}, mpe, IOperator.CONTAINS),
new BoundConstraint(new OAVAttributeType[]{OAVBDIRuntimeModel.plan_has_waitabstraction, OAVBDIRuntimeModel.waitabstraction_has_messageevents}, orig, IOperator.CONTAINS)
}));
ObjectCondition capcon = new ObjectCondition(OAVBDIRuntimeModel.capability_type);
capcon.addConstraint(new BoundConstraint(null, rcapa));
capcon.addConstraint(new BoundConstraint(OAVBDIRuntimeModel.capability_has_plans, rplan, IOperator.CONTAINS));
// ObjectCondition agentcon = new ObjectCondition(ragent.getType());
// agentcon.addConstraint(new BoundConstraint(null, ragent));
// agentcon.addConstraint(new LiteralConstraint(OAVBDIRuntimeModel.agent_has_eventprocessing, null));
// // special condition for message elements
// ObjectCondition wacon = new ObjectCondition(OAVBDIRuntimeModel.waitabstraction_type);
// wacon.addConstraint(new BoundConstraint(null, wa));
// wacon.addConstraint(new OrConstraint(new IConstraint[]
// {
// new BoundConstraint(OAVBDIRuntimeModel.waitabstraction_has_messageeventtypes, mpe, IOperator.CONTAINS),
// new BoundConstraint(OAVBDIRuntimeModel.waitabstraction_has_messageevents, orig, IOperator.CONTAINS)
// }));
Rule rule = new Rule("waitqueue_dispatch_messageevent",
new AndCondition(new ICondition[]{rpecon, plancon, capcon}), DISPATCH_WAITQUEUE_ELEMENT_ACTION);
return rule;
}
/**
* Create dispatch internal event from waitqueue rule.
*/
protected static Rule createDispatchInternalEventFromWaitqueueRule()
{
// Variable rpe = new Variable("?rpe", OAVBDIRuntimeModel.processableelement_type);
Variable rpe = new Variable("?rpe", OAVBDIRuntimeModel.internalevent_type);
Variable mpe = new Variable("?mpe", OAVBDIMetaModel.processableelement_type);
Variable rplan = new Variable("?rplan", OAVBDIRuntimeModel.plan_type);
// Variable wa = new Variable("?wa", OAVBDIRuntimeModel.waitabstraction_type);
Variable rcapa = new Variable("?rcapa", OAVBDIRuntimeModel.capability_type);
// Variable ragent = new Variable("?ragent", OAVBDIRuntimeModel.agent_type);
ObjectCondition wqcon = new ObjectCondition(rpe.getType());
wqcon.addConstraint(new BoundConstraint(null, rpe));
wqcon.addConstraint(new BoundConstraint(OAVBDIRuntimeModel.element_has_model, mpe));
ObjectCondition plancon = new ObjectCondition(OAVBDIRuntimeModel.plan_type);
plancon.addConstraint(new BoundConstraint(null, rplan));
plancon.addConstraint(new LiteralConstraint(OAVBDIRuntimeModel.plan_has_processingstate,
OAVBDIRuntimeModel.PLANPROCESSINGTATE_WAITING));
plancon.addConstraint(new BoundConstraint(OAVBDIRuntimeModel.plan_has_waitqueueelements,
rpe, IOperator.CONTAINS));
// plancon.addConstraint(new BoundConstraint(OAVBDIRuntimeModel.plan_has_waitabstraction, wa));
plancon.addConstraint(new BoundConstraint(new OAVAttributeType[]{OAVBDIRuntimeModel.plan_has_waitabstraction, OAVBDIRuntimeModel.waitabstraction_has_internaleventtypes}, mpe, IOperator.CONTAINS));
ObjectCondition capcon = new ObjectCondition(OAVBDIRuntimeModel.capability_type);
capcon.addConstraint(new BoundConstraint(null, rcapa));
capcon.addConstraint(new BoundConstraint(OAVBDIRuntimeModel.capability_has_plans, rplan, IOperator.CONTAINS));
// ObjectCondition agentcon = new ObjectCondition(ragent.getType());
// agentcon.addConstraint(new BoundConstraint(null, ragent));
// agentcon.addConstraint(new LiteralConstraint(OAVBDIRuntimeModel.agent_has_eventprocessing, null));
// special condition for internal events
// ObjectCondition wacon = new ObjectCondition(OAVBDIRuntimeModel.waitabstraction_type);
// wacon.addConstraint(new BoundConstraint(null, wa));
// wacon.addConstraint(new BoundConstraint(OAVBDIRuntimeModel.waitabstraction_has_internaleventtypes,
// mpe, IOperator.CONTAINS));
Rule rule = new Rule("waitqueue_dispatch_internalevent",
new AndCondition(new ICondition[]{wqcon, plancon, capcon}), DISPATCH_WAITQUEUE_ELEMENT_ACTION);
return rule;
}
/**
* Create dispatch goal from waitqueue rule.
* /
protected static Rule createDispatchGoalFromWaitqueueRule()
{
Variable rpe = new Variable("?rpe", OAVBDIRuntimeModel.processableelement_type);
Variable mpe = new Variable("?mpe", OAVBDIMetaModel.processableelement_type);
Variable rplan = new Variable("?rplan", OAVBDIRuntimeModel.plan_type);
Variable wa = new Variable("?wa", OAVBDIRuntimeModel.waitabstraction_type);
Variable rcapa = new Variable("?capability", OAVBDIRuntimeModel.capability_type);
// Variable ragent = new Variable("?ragent", OAVBDIRuntimeModel.agent_type);
ObjectCondition wqcon = new ObjectCondition(OAVBDIRuntimeModel.processableelement_type);
wqcon.addConstraint(new BoundConstraint(null, rpe));
wqcon.addConstraint(new BoundConstraint(OAVBDIRuntimeModel.element_has_model, mpe));
ObjectCondition plancon = new ObjectCondition(OAVBDIRuntimeModel.plan_type);
plancon.addConstraint(new BoundConstraint(null, rplan));
plancon.addConstraint(new LiteralConstraint(OAVBDIRuntimeModel.plan_has_processingstate,
OAVBDIRuntimeModel.PLANPROCESSINGTATE_WAITING));
plancon.addConstraint(new BoundConstraint(OAVBDIRuntimeModel.plan_has_waitqueueelements,
rpe, IOperator.CONTAINS));
plancon.addConstraint(new BoundConstraint(OAVBDIRuntimeModel.plan_has_waitabstraction, wa));
ObjectCondition capcon = new ObjectCondition(OAVBDIRuntimeModel.capability_type);
capcon.addConstraint(new BoundConstraint(null, rcapa));
capcon.addConstraint(new BoundConstraint(OAVBDIRuntimeModel.capability_has_plans, rplan, IOperator.CONTAINS));
// ObjectCondition agentcon = new ObjectCondition(ragent.getType());
// agentcon.addConstraint(new BoundConstraint(null, ragent));
// agentcon.addConstraint(new BoundConstraint(OAVBDIRuntimeModel.agent_has_eventprocessing, null));
// special condition for goal
ObjectCondition wacon = new ObjectCondition(OAVBDIRuntimeModel.waitabstraction_type);
wacon.addConstraint(new BoundConstraint(null, wa));
wacon.addConstraint(new BoundConstraint(OAVBDIRuntimeModel.waitabstraction_has_goals,
rpe, IOperator.CONTAINS));
Rule dispatch_element = new Rule("dispatch_goal_from_waitqueue",
new AndCondition(new ICondition[]{wqcon, plancon, capcon, wacon}), DISPATCH_WAITQUEUE_ELEMENT_ACTION);
return dispatch_element;
}*/
/**
* Rule to schedule a plan waiting for a fact added event already contained in the waitqueue.
*/
protected static Rule createDispatchFactAddedFromWaitqueueRule()
{
Variable change = new Variable("?change", OAVBDIRuntimeModel.changeevent_type);
Variable rbelset = new Variable("?rbelset", OAVBDIRuntimeModel.beliefset_type);
Variable rplan = new Variable("?rplan", OAVBDIRuntimeModel.plan_type);
Variable rcapa = new Variable("?rcapa", OAVBDIRuntimeModel.capability_type);
// Variable wa = new Variable("?wa", OAVBDIRuntimeModel.waitabstraction_type);
// Variable ragent = new Variable("?ragent", OAVBDIRuntimeModel.agent_type);
ObjectCondition wqcon = new ObjectCondition(OAVBDIRuntimeModel.changeevent_type);
wqcon.addConstraint(new BoundConstraint(null, change));
wqcon.addConstraint(new BoundConstraint(OAVBDIRuntimeModel.changeevent_has_element, rbelset));
wqcon.addConstraint(new LiteralConstraint(OAVBDIRuntimeModel.changeevent_has_type, OAVBDIRuntimeModel.CHANGEEVENT_FACTADDED));
ObjectCondition plancon = new ObjectCondition(OAVBDIRuntimeModel.plan_type);
plancon.addConstraint(new BoundConstraint(null, rplan));
plancon.addConstraint(new LiteralConstraint(OAVBDIRuntimeModel.plan_has_processingstate,
OAVBDIRuntimeModel.PLANPROCESSINGTATE_WAITING));
plancon.addConstraint(new BoundConstraint(OAVBDIRuntimeModel.plan_has_waitqueueelements,
change, IOperator.CONTAINS));
// plancon.addConstraint(new BoundConstraint(OAVBDIRuntimeModel.plan_has_waitabstraction, wa));
plancon.addConstraint(new BoundConstraint(new OAVAttributeType[]{OAVBDIRuntimeModel.plan_has_waitabstraction, OAVBDIRuntimeModel.waitabstraction_has_factaddeds}, rbelset, IOperator.CONTAINS));
ObjectCondition capcon = new ObjectCondition(OAVBDIRuntimeModel.capability_type);
capcon.addConstraint(new BoundConstraint(null, rcapa));
capcon.addConstraint(new BoundConstraint(OAVBDIRuntimeModel.capability_has_plans, rplan, IOperator.CONTAINS));
// ObjectCondition wacon = new ObjectCondition(OAVBDIRuntimeModel.waitabstraction_type);
// wacon.addConstraint(new BoundConstraint(null, wa));
// wacon.addConstraint(new BoundConstraint(OAVBDIRuntimeModel.waitabstraction_has_factaddeds, rbelset));
// ObjectCondition agentcon = new ObjectCondition(ragent.getType());
// agentcon.addConstraint(new BoundConstraint(null, ragent));
// agentcon.addConstraint(new LiteralConstraint(OAVBDIRuntimeModel.agent_has_eventprocessing, null));
Rule rule = new Rule("waitqueue_dispatch_factadded",
new AndCondition(new ICondition[]{wqcon, plancon, capcon}), DISPATCH_WAITQUEUE_ELEMENT_ACTION);
return rule;
}
/**
* Rule to schedule a plan waiting for a fact removed event already contained in the waitqueue.
*/
protected static Rule createDispatchFactRemovedFromWaitqueueRule()
{
Variable change = new Variable("?change", OAVBDIRuntimeModel.changeevent_type);
Variable rbelset = new Variable("?rbelset", OAVBDIRuntimeModel.beliefset_type);
Variable rplan = new Variable("?rplan", OAVBDIRuntimeModel.plan_type);
Variable rcapa = new Variable("?rcapa", OAVBDIRuntimeModel.capability_type);
// Variable wa = new Variable("?wa", OAVBDIRuntimeModel.waitabstraction_type);
// Variable ragent = new Variable("?ragent", OAVBDIRuntimeModel.agent_type);
ObjectCondition wqcon = new ObjectCondition(OAVBDIRuntimeModel.changeevent_type);
wqcon.addConstraint(new BoundConstraint(null, change));
wqcon.addConstraint(new BoundConstraint(OAVBDIRuntimeModel.changeevent_has_element, rbelset));
wqcon.addConstraint(new LiteralConstraint(OAVBDIRuntimeModel.changeevent_has_type, OAVBDIRuntimeModel.CHANGEEVENT_FACTREMOVED));
ObjectCondition plancon = new ObjectCondition(OAVBDIRuntimeModel.plan_type);
plancon.addConstraint(new BoundConstraint(null, rplan));
plancon.addConstraint(new LiteralConstraint(OAVBDIRuntimeModel.plan_has_processingstate,
OAVBDIRuntimeModel.PLANPROCESSINGTATE_WAITING));
plancon.addConstraint(new BoundConstraint(OAVBDIRuntimeModel.plan_has_waitqueueelements,
change, IOperator.CONTAINS));
// plancon.addConstraint(new BoundConstraint(OAVBDIRuntimeModel.plan_has_waitabstraction, wa));
plancon.addConstraint(new BoundConstraint(new OAVAttributeType[]{OAVBDIRuntimeModel.plan_has_waitabstraction, OAVBDIRuntimeModel.waitabstraction_has_factremoveds}, rbelset, IOperator.CONTAINS));
ObjectCondition capcon = new ObjectCondition(OAVBDIRuntimeModel.capability_type);
capcon.addConstraint(new BoundConstraint(null, rcapa));
capcon.addConstraint(new BoundConstraint(OAVBDIRuntimeModel.capability_has_plans, rplan, IOperator.CONTAINS));
// ObjectCondition wacon = new ObjectCondition(OAVBDIRuntimeModel.waitabstraction_type);
// wacon.addConstraint(new BoundConstraint(null, wa));
// wacon.addConstraint(new BoundConstraint(OAVBDIRuntimeModel.waitabstraction_has_factremoveds, rbelset));
// ObjectCondition agentcon = new ObjectCondition(ragent.getType());
// agentcon.addConstraint(new BoundConstraint(null, ragent));
// agentcon.addConstraint(new LiteralConstraint(OAVBDIRuntimeModel.agent_has_eventprocessing, null));
Rule rule = new Rule("waitqueue_dispatch_factremoved",
new AndCondition(new ICondition[]{wqcon, plancon, capcon}), DISPATCH_WAITQUEUE_ELEMENT_ACTION);
return rule;
}
/**
* Rule to schedule a plan waiting for a fact added event already contained in the waitqueue.
*/
protected static Rule createDispatchFactChangedFromWaitqueueRule()
{
Variable change = new Variable("?change", OAVBDIRuntimeModel.changeevent_type);
Variable rbelset = new Variable("?rbelset", OAVBDIRuntimeModel.beliefset_type);
Variable rplan = new Variable("?rplan", OAVBDIRuntimeModel.plan_type);
Variable rcapa = new Variable("?rcapa", OAVBDIRuntimeModel.capability_type);
// Variable wa = new Variable("?wa", OAVBDIRuntimeModel.waitabstraction_type);
// Variable ragent = new Variable("?ragent", OAVBDIRuntimeModel.agent_type);
ObjectCondition wqcon = new ObjectCondition(OAVBDIRuntimeModel.changeevent_type);
wqcon.addConstraint(new BoundConstraint(null, change));
wqcon.addConstraint(new BoundConstraint(OAVBDIRuntimeModel.changeevent_has_element, rbelset));
wqcon.addConstraint(new LiteralConstraint(OAVBDIRuntimeModel.changeevent_has_type, OAVBDIRuntimeModel.CHANGEEVENT_FACTCHANGED));
ObjectCondition plancon = new ObjectCondition(OAVBDIRuntimeModel.plan_type);
plancon.addConstraint(new BoundConstraint(null, rplan));
plancon.addConstraint(new LiteralConstraint(OAVBDIRuntimeModel.plan_has_processingstate,
OAVBDIRuntimeModel.PLANPROCESSINGTATE_WAITING));
plancon.addConstraint(new BoundConstraint(OAVBDIRuntimeModel.plan_has_waitqueueelements,
change, IOperator.CONTAINS));
// plancon.addConstraint(new BoundConstraint(OAVBDIRuntimeModel.plan_has_waitabstraction, wa));
plancon.addConstraint(new BoundConstraint(new OAVAttributeType[]{OAVBDIRuntimeModel.plan_has_waitabstraction, OAVBDIRuntimeModel.waitabstraction_has_factchangeds}, rbelset, IOperator.CONTAINS));
ObjectCondition capcon = new ObjectCondition(OAVBDIRuntimeModel.capability_type);
capcon.addConstraint(new BoundConstraint(null, rcapa));
capcon.addConstraint(new BoundConstraint(OAVBDIRuntimeModel.capability_has_plans, rplan, IOperator.CONTAINS));
// ObjectCondition wacon = new ObjectCondition(OAVBDIRuntimeModel.waitabstraction_type);
// wacon.addConstraint(new BoundConstraint(null, wa));
// wacon.addConstraint(new BoundConstraint(OAVBDIRuntimeModel.waitabstraction_has_factchangeds, rbelset));
// ObjectCondition agentcon = new ObjectCondition(ragent.getType());
// agentcon.addConstraint(new BoundConstraint(null, ragent));
// agentcon.addConstraint(new LiteralConstraint(OAVBDIRuntimeModel.agent_has_eventprocessing, null));
Rule rule = new Rule("waitqueue_dispatch_factchanged",
new AndCondition(new ICondition[]{wqcon, plancon, capcon}), DISPATCH_WAITQUEUE_ELEMENT_ACTION);
return rule;
}
protected static IAction DISPATCH_WAITQUEUE_ELEMENT_ACTION = new IAction()
{
public void execute(IOAVState state, IVariableAssignments assignments)
{
Object rplan = assignments.getVariableValue("?rplan");
Object rcapa = assignments.getVariableValue("?rcapa");
Object rpe = assignments.getVariableValue("?rpe");
state.setAttributeValue(rplan, OAVBDIRuntimeModel.plan_has_processingstate,
OAVBDIRuntimeModel.PLANPROCESSINGTATE_READY);
state.setAttributeValue(rplan, OAVBDIRuntimeModel.plan_has_dispatchedelement, rpe);
PlanRules.cleanupPlanWait(state, rcapa, rplan, false);
state.removeAttributeValue(rplan, OAVBDIRuntimeModel.plan_has_waitqueueelements, rpe);
// System.out.println("DISPATCH_WAITQUEUE_ELEMENT_ACTION: schedulePlanInstance: "
// +BDIInterpreter.getInterpreter(state).getAgentAdapter().getComponentIdentifier().getLocalName()
// +", "+rplan+", "+rpe);
}
};
/**
* Create the clean eventprocessing rule for non-active goals.
* // todo: Hack. Only necessary because eventprocessing state must be
* saved in OAVBDIRuntimeModel.capability_has_eventprocessing
* /
protected static Rule createRemoveEventprocessingArtifactRule()
{
Variable rgoal = new Variable("?rgoal", OAVBDIRuntimeModel.goal_type);
Variable rcapa = new Variable("?rcapa", OAVBDIRuntimeModel.capability_type);
Variable ragent = new Variable("?ragent", OAVBDIRuntimeModel.agent_type);
ObjectCondition goalcon = new ObjectCondition(rgoal.getType());
goalcon.addConstraint(new BoundConstraint(null, rgoal));
goalcon.addConstraint(new LiteralConstraint(OAVBDIRuntimeModel.goal_has_lifecyclestate,
OAVBDIRuntimeModel.GOALLIFECYCLESTATE_ACTIVE, IOperator.NOTEQUAL));
ObjectCondition capcon = new ObjectCondition(rcapa.getType());
capcon.addConstraint(new BoundConstraint(null, rcapa));
capcon.addConstraint(new BoundConstraint(OAVBDIRuntimeModel.capability_has_goals,
rgoal, IOperator.CONTAINS));
ObjectCondition agentcon = new ObjectCondition(ragent.getType());
agentcon.addConstraint(new BoundConstraint(null, ragent));
// agentcon.addConstraint(new BoundConstraint(OAVBDIRuntimeModel.agent_has_eventprocessing, rgoal));
Rule remove_eventprocessing_artifact = new Rule("remove_eventprocessing_artifact",
new AndCondition(new ICondition[]{goalcon, capcon, agentcon}), new IAction()
{
public void execute(IOAVState state, IVariableAssignments assignments)
{
Object ragent = assignments.getVariableValue("?ragent");
// Remove that event processing artifact.
// state.setAttributeValue(ragent, OAVBDIRuntimeModel.agent_has_eventprocessing, null);
}
});
return remove_eventprocessing_artifact;
}*/
//-------- helper methods --------
/**
* Create candidates for a matching mplan.
* Checks precondition and evaluates bindings (if any).
* @return apl returns new apl object in case a null apl is supplied.
*/
protected static Object createMPlanCandidates(IOAVState state, Object processable, Object rcapa, Object apl, Object mplan, OAVBDIFetcher fetcher)
{
List bindings = AgentRules.calculateBindingElements(state, mplan, null, fetcher);
if(bindings!=null)
{
for(int i=0; i<bindings.size(); i++)
{
apl = createMPlanCandidate(state, processable, rcapa, apl, mplan, fetcher, (Map)bindings.get(i));
}
}
// No binding: generate one candidate.
else
{
apl = createMPlanCandidate(state, processable, rcapa, apl, mplan, fetcher, null);
}
return apl;
}
/**
* Create candidates for a matching mplan.
* Checks precondition and evaluates bindings (if any).
* @return apl returns new apl object in case a null apl is supplied.
*/
protected static Object createMPlanCandidate(IOAVState state, Object rpe, Object rcapa, Object apl, Object mplan, final OAVBDIFetcher fetcher, final Map bindings)
{
IValueFetcher f2 = fetcher;
if(bindings!=null)
{
f2 = new IValueFetcher()
{
public Object fetchValue(String name)
{
Object ret = bindings.get(name);
if(ret==null && !bindings.containsKey(name))
ret = fetcher.fetchValue(name);
return ret;
}
public Object fetchValue(String name, Object object)
{
return fetcher.fetchValue(name, object);
}
};
}
boolean preok = true;
Object precond = state.getAttributeValue(mplan, OAVBDIMetaModel.plan_has_precondition);
if(precond!=null)
{
Object ret = AgentRules.evaluateExpression(state, precond, f2);
if(ret!=null)
preok = ((Boolean)ret).booleanValue();
}
if(preok)
{
if(apl==null)
apl = createAPL(state, rpe);
Object mplancandidate = state.createObject(OAVBDIRuntimeModel.mplancandidate_type);
state.setAttributeValue(mplancandidate, OAVBDIRuntimeModel.mplancandidate_has_mplan, mplan);
state.setAttributeValue(mplancandidate, OAVBDIRuntimeModel.mplancandidate_has_rcapa, rcapa);
// Must be added and removed to allow being used in state (otherwise state does not know object)
state.addAttributeValue(apl, OAVBDIRuntimeModel.apl_has_plancandidates, mplancandidate);
// System.out.println("EventProcessingRules.createMPlanCandidate() add: "+apl+", "+mplancandidate);
if(bindings!=null)
{
for(Iterator it=bindings.keySet().iterator(); it.hasNext(); )
{
String name = (String)it.next();
Object mparam = state.getAttributeValue(mplan, OAVBDIMetaModel.parameterelement_has_parameters, name);
Class clazz = (Class)state.getAttributeValue(mparam, OAVBDIMetaModel.typedelement_has_class);
Object rparam = BeliefRules.createParameter(state, name, bindings.get(name), clazz, null, mparam, rcapa);
state.addAttributeValue(mplancandidate, OAVBDIRuntimeModel.mplancandidate_has_bindings, rparam);
}
}
boolean remove = false;
// Test if exclude allows adding candidate.
if(state.getType(rpe).isSubtype(OAVBDIRuntimeModel.goal_type))
{
Object mgoal = state.getAttributeValue(rpe, OAVBDIRuntimeModel.element_has_model);
String excludemode = (String)state.getAttributeValue(mgoal, OAVBDIMetaModel.goal_has_exclude);
if(!OAVBDIMetaModel.EXCLUDE_NEVER.equals(excludemode))
{
List tried = (List)state.getAttributeValues(rpe, OAVBDIRuntimeModel.goal_has_triedmplans);
if(tried!=null)
{
for(int i=0; !remove && i<tried.size(); i++)
{
Object mcand = tried.get(i);
if(equalsMPlanCandidates(state, mcand, mplancandidate))
remove = true;
}
}
}
}
if(remove)
state.removeAttributeValue(apl, OAVBDIRuntimeModel.apl_has_plancandidates, mplancandidate);
}
return apl;
}
/**
* Remove a candidate from the apl.
* // Use exclude settings to decide if plan should be removed. (todo when-failed vs. when-tried ???)
* @param state The state.
* @param rgoal The goal.
* @param candidate The candidate.
* /
protected static void removeAPLCandidate(IOAVState state, Object rgoal, Object candidate)
{
Object mgoal = state.getAttributeValue(rgoal, OAVBDIRuntimeModel.element_has_model);
Object apl = state.getAttributeValue(rgoal, OAVBDIRuntimeModel.processableelement_has_apl);
OAVObjectType type = state.getType(candidate);
if(OAVBDIRuntimeModel.mplancandidate_type.equals(type))
{
if(!OAVBDIMetaModel.EXCLUDE_NEVER.equals(state.getAttributeValue(mgoal, OAVBDIMetaModel.goal_has_exclude)))
state.removeAttributeValue(apl, OAVBDIRuntimeModel.apl_has_plancandidates, candidate);
}
else //if(OAVBDIRuntimeModel.plan_type.equals(type))
{
if(!OAVBDIMetaModel.EXCLUDE_NEVER.equals(state.getAttributeValue(mgoal, OAVBDIMetaModel.goal_has_exclude)))
{
// Hack?
Collection coll = state.getAttributeValues(apl, OAVBDIRuntimeModel.apl_has_waitqueuecandidates);
if(coll!=null && coll.contains(candidate))
state.removeAttributeValue(apl, OAVBDIRuntimeModel.apl_has_waitqueuecandidates, candidate);
else
state.removeAttributeValue(apl, OAVBDIRuntimeModel.apl_has_planinstancecandidates, candidate);
}
}
}*/
/**
* Create an applicable candidate list and add it to the processable element.
* @param state The state.
* @param rpe The processable element.
* @return The apl.
*/
protected static Object createAPL(IOAVState state, Object rpe)
{
Object apl = state.createObject(OAVBDIRuntimeModel.apl_type);
state.setAttributeValue(rpe, OAVBDIRuntimeModel.processableelement_has_apl, apl);
// System.out.println("Created apl for: "+rpe+" "+apl);
return apl;
}
/**
* The reasoning method.
* @param event The event.
* @param candidatelist The list of candidates.
* @return The selected candidates.
*/
protected static List reason(IOAVState state, Object rpe, Object apl)
{
if(apl==null)
System.out.println("APL must not be null: "+rpe);
// Use the plan priorities to sort the candidates.
// If the priority is the same use the following order:
// running plan - waitque of running plan - passive plan
ArrayList selected = SCollection.createArrayList();
// todo: include a number of retries...
int numcandidates = 1;
Object mpe = state.getAttributeValue(rpe, OAVBDIRuntimeModel.element_has_model);
Boolean posttoall = (Boolean)state.getAttributeValue(mpe, OAVBDIMetaModel.processableelement_has_posttoall);
if(posttoall!=null && posttoall.booleanValue())
numcandidates = Integer.MAX_VALUE;
List candidatelist = SCollection.createArrayList();
Collection coll = state.getAttributeValues(apl, OAVBDIRuntimeModel.apl_has_planinstancecandidates);
if(coll!=null)
{
for(Iterator it=coll.iterator(); it.hasNext(); )
{
// Plan can be aborted/timouted/etc. during reasoning.
// Have to check if candidate is still valid.
// Hack!!! Cannot check if still waiting for same event
Object cand = it.next();
// Object rplan = state.getAttributeValue(cand, OAVBDIRuntimeModel.plancandidate_has_plan);
// if(OAVBDIRuntimeModel.PLANPROCESSINGTATE_WAITING.equals(state.getAttributeValue(rplan, OAVBDIRuntimeModel.plan_has_processingstate)))
candidatelist.add(cand);
}
}
coll = state.getAttributeValues(apl, OAVBDIRuntimeModel.apl_has_waitqueuecandidates);
if(coll!=null)
{
for(Iterator it=coll.iterator(); it.hasNext(); )
{
candidatelist.add(it.next());
}
}
coll = state.getAttributeValues(apl, OAVBDIRuntimeModel.apl_has_plancandidates);
if(coll!=null)
candidatelist.addAll(coll);
Boolean tmp = (Boolean)state.getAttributeValue(mpe, OAVBDIMetaModel.processableelement_has_randomselection);
boolean random = tmp==null? false: tmp.booleanValue();
for(int i=0; i<numcandidates && candidatelist.size()>0; i++)
selected.add(getNextCandidate(state, candidatelist, random, apl));
return selected;
}
//-------- helper methods --------
/**
* Get the next candidate with respect to the plan
* priority and the rank of the candidate.
* @param candidatelist The candidate list.
* @param random The random selection flag.
* @return The next candidate.
*/
protected static Object getNextCandidate(IOAVState state, List candidatelist, boolean random, Object apl)
{
List finals = SCollection.createArrayList();
finals.add(candidatelist.get(0));
int candprio = getPriority(state, finals.get(0));
for(int i=1; i<candidatelist.size(); i++)
{
Object tmp = candidatelist.get(i);
int tmpprio = getPriority(state, tmp);
if(tmpprio>candprio
|| (tmpprio == candprio && getRank(state, tmp, apl)>getRank(state, finals.get(0), apl)))
{
finals.clear();
finals.add(tmp);
candprio = tmpprio;
}
else if(tmpprio==candprio && getRank(state, tmp, apl)==getRank(state, finals.get(0), apl))
{
finals.add(tmp);
}
}
Object cand;
if(random)
{
int rand = (int)(Math.random()*finals.size());
cand = finals.get(rand);
//System.out.println("Random sel: "+finals.size()+" "+rand+" "+cand);
}
else
{
//System.out.println("First sel: "+finals.size()+" "+0);
cand = finals.get(0);
}
candidatelist.remove(cand);
return cand;
}
/**
* Get the priority of a candidate.
* @return The priority of a candidate.
*/
protected static int getPriority(IOAVState state, Object cand)
{
Object mplan;
if(state.getType(cand).equals(OAVBDIRuntimeModel.waitqueuecandidate_type))
{
Object rplan = state.getAttributeValue(cand, OAVBDIRuntimeModel.waitqueuecandidate_has_plan);
mplan = state.getAttributeValue(rplan, OAVBDIRuntimeModel.element_has_model);
}
else if(state.getType(cand).equals(OAVBDIRuntimeModel.plancandidate_type))
{
Object rplan = state.getAttributeValue(cand, OAVBDIRuntimeModel.plancandidate_has_plan);
mplan = state.getAttributeValue(rplan, OAVBDIRuntimeModel.element_has_model);
}
else // if(state.getType(cand).equals(OAVBDIRuntimeModel.mplancandidate_type))
{
mplan = state.getAttributeValue(cand, OAVBDIRuntimeModel.mplancandidate_has_mplan);
}
Integer prio = (Integer)state.getAttributeValue(mplan, OAVBDIMetaModel.plan_has_priority);
return prio==null? 0: prio.intValue();
}
/**
* Get the rank of a candidate.
* The order is as follows:
* running plan (0) -> waitqueue (1) -> plan instance (2).
* @return The rank of a candidate.
*/
protected static int getRank(IOAVState state, Object cand, Object apl)
{
int rank;
if(state.getType(cand).equals(OAVBDIRuntimeModel.waitqueuecandidate_type))
{
rank = 1; // waitqueue
}
else if(state.getType(cand).equals(OAVBDIRuntimeModel.mplancandidate_type))
{
rank = 0; // mplan
}
else //if(state.getType(cand).equals(OAVBDIRuntimeModel.plancandidate_type))
{
rank = 2; // running plan
}
return rank;
}
/**
* Check the selected candidates.
* @param state The state.
* @param rcapa The capability.
* @param rpe The processable element.
* @param apl The applicable candidate list.
* @param cands The candidate List.
* @return The invalid candidate or null if all candidates valid.
*/
protected static Object checkCandidates(IOAVState state, Object rpe, Object apl, List cands)
{
// Assure that selected candidates are still valid.
// Checks for each rplan and waitqueue element if
// it still waits for such an element.
// Note that this check must not be totally correct
// in the sense that it might return true but only because
// more than one trigger may match (e.g. reply and template match)
// todo: Use some kind of version tracking of waitabstractions?!
Object cand = null;
boolean ok = true;
for(int i=0; ok && i<cands.size(); i++)
{
cand = cands.get(i);
Object wa;
if(state.getType(cand).equals(OAVBDIRuntimeModel.waitqueuecandidate_type))
{
Object rplan = state.getAttributeValue(cand, OAVBDIRuntimeModel.waitqueuecandidate_has_plan);
wa = state.getAttributeValue(rplan, OAVBDIRuntimeModel.plan_has_waitqueuewa);
}
else if(state.getType(cand).equals(OAVBDIRuntimeModel.plancandidate_type))
{
Object rplan = state.getAttributeValue(cand, OAVBDIRuntimeModel.plancandidate_has_plan);
wa = state.getAttributeValue(rplan, OAVBDIRuntimeModel.plan_has_waitabstraction);
}
else
{
continue;
}
if(wa==null)
{
ok = false;
}
else
{
// Belief changes need not be checked because they are posttoall and do not build an apl.
if(state.getType(rpe).isSubtype(OAVBDIRuntimeModel.goal_type))
{
Collection coll = (Collection)state.getAttributeValues(wa, OAVBDIRuntimeModel.waitabstraction_has_goalfinisheds);
ok = coll!=null && coll.contains(rpe);
}
else if(state.getType(rpe).isSubtype(OAVBDIRuntimeModel.internalevent_type))
{
Collection coll = (Collection)state.getAttributeValues(wa, OAVBDIRuntimeModel.waitabstraction_has_internaleventtypes);
Object mpe = state.getAttributeValue(rpe, OAVBDIRuntimeModel.element_has_model);
ok = coll!=null && coll.contains(mpe);
}
else if(state.getType(rpe).isSubtype(OAVBDIRuntimeModel.messageevent_type))
{
Collection coll = (Collection)state.getAttributeValues(wa, OAVBDIRuntimeModel.waitabstraction_has_messageevents);
Object org = state.getAttributeValue(rpe, OAVBDIRuntimeModel.messageevent_has_original);
ok = coll!=null && coll.contains(org);
if(!ok)
{
coll = (Collection)state.getAttributeValues(wa, OAVBDIRuntimeModel.waitabstraction_has_messageeventtypes);
Object mpe = state.getAttributeValue(rpe, OAVBDIRuntimeModel.element_has_model);
ok = coll.contains(mpe);
}
}
}
}
return ok? null: cand;
}
/**
* Schedule the selected candidates.
* @param state The state.
* @param rcapa The capability.
* @param rpe The processable element.
* @param apl The applicable candidate list.
* @param cands The candidate List.
*/
protected static void scheduleCandidates(IOAVState state, Object rpe, Object apl, List cands)
{
for(int i=0; i<cands.size(); i++)
{
Object cand = cands.get(i);
scheduleCandidate(state, rpe, apl, cand);
}
}
/**
* Schedule a candidate.
*/
protected static void scheduleCandidate(IOAVState state, Object rpe, Object apl, Object cand)
{
if(state.getType(cand).equals(OAVBDIRuntimeModel.waitqueuecandidate_type))
{
Object rplan = state.getAttributeValue(cand, OAVBDIRuntimeModel.waitqueuecandidate_has_plan);
scheduleWaitqueueCandidate(state, rpe, rplan);
// Save candidate in plan for later apl removal and exclude list management.
if(state.getType(rpe).isSubtype(OAVBDIRuntimeModel.goal_type))
state.setAttributeValue(state.getAttributeValue(cand, OAVBDIRuntimeModel.waitqueuecandidate_has_plan)
, OAVBDIRuntimeModel.plan_has_waitqueuecandidate, cand);
}
else if(state.getType(cand).equals(OAVBDIRuntimeModel.mplancandidate_type))
{
Object rplan = schedulePlanCandidate(state, rpe, cand);
// Save candidate in plan for later apl removal and exclude list management.
if(state.getType(rpe).isSubtype(OAVBDIRuntimeModel.goal_type))
state.setAttributeValue(rplan, OAVBDIRuntimeModel.plan_has_plancandidate, cand);
}
else //if(state.getType(cand).equals(OAVBDIRuntimeModel.plancandidate_type))
{
Object rplan = state.getAttributeValue(cand, OAVBDIRuntimeModel.plancandidate_has_plan);
Object rcapa = state.getAttributeValue(cand, OAVBDIRuntimeModel.plancandidate_has_rcapa);
schedulePlanInstanceCandidate(state, rpe, rplan, rcapa);
// Save candidate in plan for later apl removal and exclude list management.
if(state.getType(rpe).isSubtype(OAVBDIRuntimeModel.goal_type))
{
// Object rplan = state.getAttributeValue(cand, OAVBDIRuntimeModel.plancandidate_has_plan);
state.setAttributeValue(rplan, OAVBDIRuntimeModel.plan_has_planinstancecandidate, cand);
}
}
}
/**
* Schedule a plan candidate.
*/
protected static Object schedulePlanCandidate(IOAVState state, Object rpe, Object cand)
{
Object mplan = state.getAttributeValue(cand, OAVBDIRuntimeModel.mplancandidate_has_mplan);
Object rcapa = state.getAttributeValue(cand, OAVBDIRuntimeModel.mplancandidate_has_rcapa);
Collection bindings = state.getAttributeValues(cand, OAVBDIRuntimeModel.mplancandidate_has_bindings);
Object rplan = PlanRules.instantiatePlan(state, rcapa, mplan, null, rpe, bindings, null, null);
PlanRules.adoptPlan(state, rcapa, rplan);
state.setAttributeValue(rpe, OAVBDIRuntimeModel.processableelement_has_state,
OAVBDIRuntimeModel.PROCESSABLEELEMENT_CANDIDATESSELECTED);
return rplan;
}
/**
* Schedule a plan instance candidate.
*/
public static void schedulePlanInstanceCandidate(IOAVState state, Object dispelem, Object rplan, Object rcapa)//Object cand)
{
// System.out.println("schedulePlanInstanceCandidate: Setting plan to ready: "
// +BDIInterpreter.getInterpreter(state).getAgentAdapter().getComponentIdentifier().getLocalName()
// +", "+rplan);
// Object rplan = state.getAttributeValue(cand, OAVBDIRuntimeModel.plancandidate_has_plan);
// Object rcapa = state.getAttributeValue(cand, OAVBDIRuntimeModel.plancandidate_has_rcapa);
state.setAttributeValue(rplan, OAVBDIRuntimeModel.plan_has_processingstate,
OAVBDIRuntimeModel.PLANPROCESSINGTATE_READY);
state.setAttributeValue(rplan, OAVBDIRuntimeModel.plan_has_dispatchedelement, dispelem);
PlanRules.cleanupPlanWait(state, rcapa, rplan, false);
if(dispelem!=null && state.getType(dispelem).isSubtype(OAVBDIRuntimeModel.processableelement_type))
{
state.setAttributeValue(dispelem, OAVBDIRuntimeModel.processableelement_has_state,
OAVBDIRuntimeModel.PROCESSABLEELEMENT_CANDIDATESSELECTED);
}
}
/**
* Schedule a waitqueue candidate.
*/
protected static void scheduleWaitqueueCandidate(IOAVState state, Object rpe, Object rplan)
{
state.addAttributeValue(rplan, OAVBDIRuntimeModel.plan_has_waitqueueelements, rpe);
}
/**
* Test if two plan candidates are equal.
* @param state The state.
* @param mplancand1 The first candidate.
* @param mplancand2 The second candidate.
* @return True, if equal.
*/
protected static boolean equalsMPlanCandidates(IOAVState state, Object mplancand1, Object mplancand2)
{
if(mplancand1==mplancand2)
return true;
if(mplancand1==null || mplancand2==null)
return false;
Object mplan1 = state.getAttributeValue(mplancand1, OAVBDIRuntimeModel.mplancandidate_has_mplan);
Object mplan2 = state.getAttributeValue(mplancand2, OAVBDIRuntimeModel.mplancandidate_has_mplan);
boolean ret = mplan1==mplan2;
if(ret)
{
List binds1 = (List)state.getAttributeValues(mplancand1, OAVBDIRuntimeModel.mplancandidate_has_bindings);
List binds2 = (List)state.getAttributeValues(mplancand1, OAVBDIRuntimeModel.mplancandidate_has_bindings);
ret = equalsBindings(state, binds1, binds2);
}
return ret;
}
/**
* Test if two bindinds are equal.
* @param state The state.
* @param binds1 The first bindings.
* @param binds2 The second bindings.
* @return True, if equal.
*/
protected static boolean equalsBindings(IOAVState state, List binds1, List binds2)
{
if(binds1==binds2)
return true;
if(binds1==null || binds2==null)
return false;
boolean ret = binds1.size()==binds2.size();
// Assume same parameter ordering (Hack)?!
for(int i=0; ret && i<binds1.size(); i++)
{
Object param1 = binds1.get(i);
Object param2 = binds2.get(i);
ret = equalsParam(state, param1, param2);
}
return ret;
}
/**
* Test if two parameters are equal.
* @param state The state.
* @param param1 The first runtime parameter.
* @param param2 The second runtime parameter.
* @return True, if equal.
*/
protected static boolean equalsParam(IOAVState state, Object param1, Object param2)
{
if(param1==param2)
return true;
if(param1==null || param2==null)
return false;
String name1 = (String)state.getAttributeValue(param1, OAVBDIRuntimeModel.parameter_has_name);
Object value1 = state.getAttributeValue(param1, OAVBDIRuntimeModel.parameter_has_value);
String name2 = (String)state.getAttributeValue(param2, OAVBDIRuntimeModel.parameter_has_name);
Object value2 = state.getAttributeValue(param2, OAVBDIRuntimeModel.parameter_has_value);
return SUtil.equals(name1, name2) && SUtil.equals(value1, value2);
}
/**
* Marker class for distinguishing between plan instance
* candidates and waitqueue candidates (both plan_type).
* /
static class WaitqueueCandidate
{
/** The waitqueue candidate. * /
protected Object waitqueuecandidate;
/**
* Create a new {@link WaitqueueCandidate} candidate.
* /
public WaitqueueCandidate(Object waitqueuecandidate)
{
this.waitqueuecandidate = waitqueuecandidate;
}
/**
* Get the waitqueuecandidate.
* @return The waitqueuecandidate.
* /
public Object getWaitqueueCandidate()
{
return waitqueuecandidate;
}
}*/
}