RevertingCapability.java

105 lines | 3.181 kB Blame History Raw Download
package bdi4jade.extension.undo;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import bdi4jade.belief.PredicateBelief;
import bdi4jade.core.Capability;
import bdi4jade.event.BeliefEvent;
import bdi4jade.event.BeliefEvent.Action;
import bdi4jade.event.BeliefListener;
import bdi4jade.event.GoalEvent;
import bdi4jade.event.GoalListener;
import bdi4jade.extension.remediation.logics.Predicate;
import bdi4jade.extension.undo.reasoning.RevertingOptionGenerationFunction;
import bdi4jade.goal.Goal;
import bdi4jade.goal.GoalStatus;
import bdi4jade.goal.PredicateGoal;

public class RevertingCapability extends Capability implements BeliefListener, GoalListener {

	private static final long serialVersionUID = -5556551069331273755L;

	private final Map<Goal, GoalAchievementMetadata> gams;
	private final Map<Goal, Goal> parentGoals;

	public RevertingCapability() {
		this.gams = new HashMap<>();
		this.parentGoals = new HashMap<>();
		setOptionGenerationFunction(new RevertingOptionGenerationFunction(this));
		this.getMyAgent().addGoalListener(this);
		this.getBeliefBase().addBeliefListener(this);
	}

	public void addGoalAchievementMetadata(Goal goal, GoalAchievementMetadata gam) {
		this.gams.put(goal, gam);
	}

	public void addParentGoal(Goal goal, Goal parent) {
		this.parentGoals.put(goal, parent);
	}

	public GoalAchievementMetadata createGoalAchievementMetadata(Goal goal, List<Predicate> reversionTrigger,
			Boolean rollback, Integer maxExecutedPlans, Integer maxTime) {
		GoalAchievementMetadata gam = new GoalAchievementMetadata((PredicateGoal<?>) goal, reversionTrigger, rollback,
				maxExecutedPlans, maxTime);
		addGoalAchievementMetadata(goal, gam);
		return gam;
	}

	@Override
	public void eventOccurred(BeliefEvent beliefEvent) {
		if (beliefEvent.getAction().equals(Action.BELIEF_UPDATED) && beliefEvent.getArgs() != null) {
			Object args = beliefEvent.getArgs();
			if (args instanceof PredicateGoal<?>) {
				PredicateGoal<?> goal = (PredicateGoal<?>) args;
				// TODO Here, get the oldest reversible parent.
				if (beliefEvent.getBelief() instanceof PredicateBelief<?>) {
					PredicateBelief<?> belief = (PredicateBelief<?>) beliefEvent.getBelief();
					Goal oldestParent = getOldestReversibleParent(goal);
					if (oldestParent != null) {
						this.gams.get(oldestParent).trackBeliefChange((Predicate) belief.getName(), belief.getValue());
					}
				}
			}
		}
	}

	private Goal getOldestReversibleParent(Goal goal) {
		Goal parent = null;
		Goal aux = goal;

		if (this.gams.containsKey(goal)) {
			parent = goal;
		}

		while (this.parentGoals.containsKey(aux)) {
			aux = this.parentGoals.get(aux);
			if (this.gams.containsKey(aux)) {
				parent = this.parentGoals.get(aux);
			}
		}

		return parent;
	}

	public Map<Goal, GoalAchievementMetadata> getGoalAchievementMetadata() {
		return gams;
	}

	public Map<Goal, Goal> getParentGoals() {
		return parentGoals;
	}

	@Override
	public void goalPerformed(GoalEvent event) {
		for (GoalAchievementMetadata gam : gams.values()) {
			if (gam.getIntention().getStatus().equals(GoalStatus.ACHIEVED) && !event.getGoal().equals(gam.getGoal())
					&& event.getStatus().equals(GoalStatus.ACHIEVED)) {
				gam.incrementPlanCounter();
			}
		}
	}
}