BDI2DoSCapability.java

628 lines | 21.519 kB Blame History Raw Download
package br.ufrgs.inf.bdinetr.palliative;

import java.util.HashSet;
import java.util.Iterator;
import java.util.Observable;
import java.util.Observer;
import java.util.Set;

import bdi4jade.annotation.Parameter;
import bdi4jade.annotation.Parameter.Direction;
import bdi4jade.belief.Belief;
import bdi4jade.belief.BeliefSet;
import bdi4jade.belief.PredicateBelief;
import bdi4jade.belief.TransientBelief;
import bdi4jade.belief.TransientBeliefSet;
import bdi4jade.core.GoalUpdateSet;
import bdi4jade.event.GoalEvent;
import bdi4jade.event.GoalListener;
import bdi4jade.extension.palliative.PlanRequiredResource;
import bdi4jade.extension.palliative.Resource;
import bdi4jade.extension.palliative.ResourcePreferences;
import bdi4jade.extension.palliative.goal.ConstrainedGoal;
import bdi4jade.extension.palliative.goal.ObjectiveFunction;
import bdi4jade.extension.palliative.graph.AlternativeCauseSet;
import bdi4jade.extension.palliative.graph.CauseEffectKnowledgeModel;
import bdi4jade.extension.palliative.graph.CauseEffectRelationship;
import bdi4jade.extension.palliative.logics.Fact;
import bdi4jade.extension.palliative.logics.MathExpression;
import bdi4jade.extension.palliative.logics.MathExpression.Operator;
import bdi4jade.extension.palliative.logics.UnaryPredicate;
import bdi4jade.extension.palliative.reasoning.PalliativeOptionGenerationFunction;
import bdi4jade.extension.palliative.reasoning.PalliativePlanSelectionStrategy;
import bdi4jade.goal.BeliefGoal;
import bdi4jade.goal.BeliefValueGoal;
import bdi4jade.goal.Goal;
import bdi4jade.goal.GoalStatus;
import bdi4jade.goal.GoalTemplate;
import bdi4jade.goal.GoalTemplateFactory;
import bdi4jade.goal.PredicateGoal;
import bdi4jade.plan.DefaultPlan;
import bdi4jade.plan.Plan;
import bdi4jade.plan.Plan.EndState;
import bdi4jade.plan.planbody.BeliefGoalPlanBody;
import bdi4jade.reasoning.BeliefRevisionStrategy;
import br.ufrgs.inf.bdinetr.agent.FlowExporterCapability;
import br.ufrgs.inf.bdinetr.agent.RateLimiterCapability;
import br.ufrgs.inf.bdinetr.agent.RouterAgentCapability;
import br.ufrgs.inf.bdinetr.agent.belief.AnomalousUsageBelief;
import br.ufrgs.inf.bdinetr.agent.belief.BenignBelief;
import br.ufrgs.inf.bdinetr.domain.AnomalyDetection;
import br.ufrgs.inf.bdinetr.domain.Classifier;
import br.ufrgs.inf.bdinetr.domain.Flow;
import br.ufrgs.inf.bdinetr.domain.FlowExporter;
import br.ufrgs.inf.bdinetr.domain.Ip;
import br.ufrgs.inf.bdinetr.domain.Link;
import br.ufrgs.inf.bdinetr.domain.LinkMonitor;
import br.ufrgs.inf.bdinetr.domain.RateLimiter;
import br.ufrgs.inf.bdinetr.domain.Role;
import br.ufrgs.inf.bdinetr.domain.Router;
import br.ufrgs.inf.bdinetr.domain.predicate.Anomalous;
import br.ufrgs.inf.bdinetr.domain.predicate.AnomalousUsage;
import br.ufrgs.inf.bdinetr.domain.predicate.AttackPrevented;
import br.ufrgs.inf.bdinetr.domain.predicate.Benign;
import br.ufrgs.inf.bdinetr.domain.predicate.FlowExport;
import br.ufrgs.inf.bdinetr.domain.predicate.FlowRateLimited;
import br.ufrgs.inf.bdinetr.domain.predicate.IpRateLimited;
import br.ufrgs.inf.bdinetr.domain.predicate.LinkRateLimited;
import br.ufrgs.inf.bdinetr.domain.predicate.OverUsage;
import br.ufrgs.inf.bdinetr.domain.predicate.OverUsageCause;
import br.ufrgs.inf.bdinetr.domain.predicate.Restricted;
import br.ufrgs.inf.bdinetr.domain.predicate.Threat;

public class BDI2DoSCapability extends RouterAgentCapability implements BeliefRevisionStrategy, GoalListener, Observer {

	public class OverUsageGoal extends ConstrainedGoal {

		public OverUsageGoal(Link link, Boolean value) {
			super(new PredicateGoal<OverUsage>(new OverUsage(link), false));

			this.addOperationConstraint(new MathExpression<Resource>(Resources.VULNERABILITY, Operator.LESS_THAN, 0.5));

			this.addObjectiveFunction(Resources.TIME, ObjectiveFunction.MINIMIZE);
			this.addObjectiveFunction(Resources.NETWORK_AVAILABILITY, ObjectiveFunction.MAXIMIZE);
			this.addObjectiveFunction(Resources.VULNERABILITY, ObjectiveFunction.MINIMIZE);
		}

	}

	public class LimitLinkRate extends BeliefGoalPlanBody {
		private static final long serialVersionUID = -3493377510830902961L;

		private Link link;
		private boolean subgoalDispatched;

		@Override
		public void execute() {
			if (!subgoalDispatched) {
				dispatchSubgoalAndListen(new BeliefValueGoal<>(new LinkRateLimited(link), true));
				this.subgoalDispatched = true;
			} else {
				GoalEvent event = getGoalEvent();
				if (event != null) {
					if (GoalStatus.ACHIEVED.equals(event.getStatus())) {
						addBelief(((BeliefGoal<?>) event.getGoal()).getOutputBelief());
						belief(new AttackPrevented(link), true);
					} else {
						setEndState(EndState.FAILED);
					}
				}
			}
		}

		@Override
		protected void init() {
			this.subgoalDispatched = false;
		}

		@Parameter(direction = Direction.IN)
		public void setBeliefName(UnaryPredicate<Link> attackPrevented) {
			this.link = attackPrevented.getVariable();
		}
	}

	public class RestoreLinkRate extends BeliefGoalPlanBody {
		private static final long serialVersionUID = -3493377510830902961L;

		private Link link;
		private boolean subgoalDispatched;

		@Override
		public void execute() {
			if (!subgoalDispatched) {
				dispatchSubgoalAndListen(new BeliefValueGoal<>(new LinkRateLimited(link), false));
				this.subgoalDispatched = true;
			} else {
				GoalEvent event = getGoalEvent();
				if (event != null) {
					if (GoalStatus.ACHIEVED.equals(event.getStatus())) {
						addBelief(((BeliefGoal<?>) event.getGoal()).getOutputBelief());
						belief(new AttackPrevented(link), false);
						belief(new AnomalousUsage(link), null);
					} else {
						setEndState(EndState.FAILED);
					}
				}
			}
		}

		@Override
		protected void init() {
			this.subgoalDispatched = false;
		}

		@Parameter(direction = Direction.IN)
		public void setBeliefName(AttackPrevented attackPrevented) {
			this.link = attackPrevented.getVariable();
		}
	}

	public class AnalyseLinkStatistics extends BeliefGoalPlanBody {
		private static final long serialVersionUID = -3493377510830902961L;

		private Link link;

		@Override
		public void execute() {
			Set<Ip> outliers = getAnomalyDetection().detectIntrusion(link);
			BeliefSet<OverUsageCause, Ip> overUsageCause = new TransientBeliefSet<OverUsageCause, Ip>(
					new OverUsageCause(link));
			if (outliers != null && !outliers.isEmpty()) {
				for (Ip outlier : outliers) {
					belief(new Anomalous(outlier), true);
					belief(new Benign(outlier), null);
					overUsageCause.addValue(outlier);
				}
			}
			addBelief(overUsageCause);
			addBelief(new AnomalousUsageBelief(new AnomalousUsage(link)));
		}

		@Parameter(direction = Direction.IN)
		public void setBeliefName(AnomalousUsage anomalousUsage) {
			this.link = anomalousUsage.getVariable();
		}
	}

	public class LimitIPRatePlan extends BeliefGoalPlanBody {
		private static final long serialVersionUID = -3493377510830902961L;

		private Ip ip;
		private boolean subgoalDispatched;

		@Override
		public void execute() {
			if (!subgoalDispatched) {
				dispatchSubgoalAndListen(new BeliefValueGoal<>(new IpRateLimited(ip), true));
				this.subgoalDispatched = true;
			} else {
				GoalEvent event = getGoalEvent();
				if (event != null) {
					if (GoalStatus.ACHIEVED.equals(event.getStatus())) {
						addBelief(((BeliefGoal<?>) event.getGoal()).getOutputBelief());
						belief(new Restricted(ip), true);

						Set<Belief<?, ?>> overUsageCauseBeliefs = getBeliefBase()
								.getBeliefsByType(OverUsageCause.class);
						Iterator<Belief<?, ?>> it = overUsageCauseBeliefs.iterator();
						while (it.hasNext()) {
							BeliefSet<OverUsageCause, Ip> overUsageCause = (BeliefSet<OverUsageCause, Ip>) it.next();
							if (overUsageCause.hasValue(ip)) {
								// ip in OverUsageCause(l) --> remove
								overUsageCause.removeValue(ip);
							}
						}
						belief(new Anomalous(ip), false);
					} else {
						setEndState(EndState.FAILED);
					}
				}
			}
		}

		@Override
		protected void init() {
			this.subgoalDispatched = false;
		}

		@Parameter(direction = Direction.IN)
		public void setBeliefName(UnaryPredicate<Ip> restricted) {
			this.ip = restricted.getVariable();
		}
	}

	public class RestoreIPRatePlan extends BeliefGoalPlanBody {
		private static final long serialVersionUID = -3493377510830902961L;

		private Ip ip;
		private boolean subgoalDispatched;

		@Override
		public void execute() {
			if (!subgoalDispatched) {
				dispatchSubgoalAndListen(new BeliefValueGoal<>(new IpRateLimited(ip), false));
				this.subgoalDispatched = true;
			} else {
				GoalEvent event = getGoalEvent();
				if (event != null) {
					if (GoalStatus.ACHIEVED.equals(event.getStatus())) {
						addBelief(((BeliefGoal<?>) event.getGoal()).getOutputBelief());
						belief(new Restricted(ip), false);
						belief(new Anomalous(ip), null);
					} else {
						setEndState(EndState.FAILED);
					}
				}
			}
		}

		@Override
		protected void init() {
			this.subgoalDispatched = false;
		}

		@Parameter(direction = Direction.IN)
		public void setBeliefName(Restricted restricted) {
			this.ip = restricted.getVariable();
		}
	}

	public class AnalyseIPFlows extends BeliefGoalPlanBody {
		private static final long serialVersionUID = -3493377510830902961L;

		private Ip ip;
		private boolean subgoalDispatched;

		@Override
		public void execute() {
			if (!subgoalDispatched) {
				dispatchSubgoalAndListen(new FlowExport(ip));
				this.subgoalDispatched = true;
			} else {
				GoalEvent event = getGoalEvent();
				if (event != null) {
					if (GoalStatus.ACHIEVED.equals(event.getStatus())) {
						Set<Flow> malicious = getClassifier().classifyFlows(ip);
						for (Flow flow : malicious) {
							belief(new Threat(flow), true);
						}
						addBelief(new BenignBelief(new Benign(ip)));
					} else {
						setEndState(EndState.FAILED);
					}
				} else {
					block();
				}
			}
		}

		@Override
		public void init() {
			this.subgoalDispatched = false;
		}

		@Parameter(direction = Direction.IN)
		public void setBeliefName(Benign benign) {
			this.ip = benign.getVariable();
		}
	}

	public class LimitFlowRatePlan extends BeliefGoalPlanBody {
		private static final long serialVersionUID = -3493377510830902961L;

		private Flow flow;
		private boolean subgoalDispatched;

		@Override
		public void execute() {
			if (!subgoalDispatched) {
				dispatchSubgoalAndListen(new BeliefValueGoal<>(new FlowRateLimited(flow), true));
				this.subgoalDispatched = true;
			} else {
				GoalEvent event = getGoalEvent();
				if (event != null) {
					if (GoalStatus.ACHIEVED.equals(event.getStatus())) {
						addBelief(((BeliefGoal<?>) event.getGoal()).getOutputBelief());
						belief(new Threat(flow), false);
					} else {
						setEndState(EndState.FAILED);
					}
				}
			}
		}

		@Override
		protected void init() {
			this.subgoalDispatched = false;
		}

		@Parameter(direction = Direction.IN)
		public void setBeliefName(Threat threat) {
			this.flow = threat.getVariable();
		}
	}

	public static final String ROUTER_BELIEF = "router";
	private static final long serialVersionUID = 4633237702870865396L;

	@bdi4jade.annotation.Belief
	private final Belief<String, Router> router;

	@bdi4jade.annotation.Belief
	protected CauseEffectKnowledgeModel causeEffectKnowledgeModel = new CauseEffectKnowledgeModel();

	@bdi4jade.annotation.Belief
	protected ResourcePreferences preferences = new ResourcePreferences();

	@bdi4jade.annotation.Plan
	private Plan limitLinkRate;
	@bdi4jade.annotation.Plan
	private Plan restoreLinkRate;

	@bdi4jade.annotation.Plan
	private Plan analyseLinkStatistics;
	@bdi4jade.annotation.Plan
	private Plan limitIpRate;
	@bdi4jade.annotation.Plan
	private Plan restoreIpRate;

	@bdi4jade.annotation.Plan
	private Plan analyseIpFlows;
	@bdi4jade.annotation.Plan
	private Plan limitFlowRate;

	public BDI2DoSCapability(Router router) {
		this.router = new TransientBelief<>(ROUTER_BELIEF, router);
		getLinkMonitor().addObserver(this);

		setBeliefRevisionStrategy(this);
		setOptionGenerationFunction(new MyGoalGenerationFunction());
		setPlanSelectionStrategy(new PalliativePlanSelectionStrategy(this));

		addPartCapability(new RateLimiterCapability(getRateLimiter()));
		addPartCapability(new FlowExporterCapability(getFlowExporter()));

		// Cause-Effect Knowledge Model
		CauseEffectRelationship cer = new CauseEffectRelationship(
				new Fact(new OverUsage(new Link("AFFECTED_LINK")), true));
		cer.addOptionalCause(new Fact(new AnomalousUsage(new Link("AFFECTED_LINK")), true));
		AlternativeCauseSet alternatives = new AlternativeCauseSet(1, 2);
		alternatives.addAlternativeCause(new Fact(new Anomalous(new Ip("victim1")), true));
		alternatives.addAlternativeCause(new Fact(new Anomalous(new Ip("victim2")), true));
		cer.addAlternativeCauseSet(alternatives);
		causeEffectKnowledgeModel.addCauseEffectRelationship(cer);

		cer = new CauseEffectRelationship(new Fact(new Anomalous(new Ip("victim1")), true));
		cer.addOptionalCause(new Fact(new Benign(new Ip("victim1")), false));
		alternatives = new AlternativeCauseSet(1, 2);
		alternatives.addAlternativeCause(
				new Fact(new Threat(new Flow(new Ip("DDoS1"), 80, new Ip("victim1"), 80, "http")), true));
		alternatives.addAlternativeCause(
				new Fact(new Threat(new Flow(new Ip("DDoS2"), 80, new Ip("victim1"), 80, "http")), true));
		cer.addAlternativeCauseSet(alternatives);
		causeEffectKnowledgeModel.addCauseEffectRelationship(cer);

		cer = new CauseEffectRelationship(new Fact(new Anomalous(new Ip("victim2")), true));
		cer.addOptionalCause(new Fact(new Benign(new Ip("victim2")), false));
		alternatives = new AlternativeCauseSet(1, 1);
		alternatives.addAlternativeCause(
				new Fact(new Threat(new Flow(new Ip("DDoS3"), 80, new Ip("victim2"), 80, "http")), true));
		cer.addAlternativeCauseSet(alternatives);
		causeEffectKnowledgeModel.addCauseEffectRelationship(cer);

		// Resource Preferences
		preferences.getValue().put(Resources.TIME, 0.75);
		preferences.getValue().put(Resources.NETWORK_AVAILABILITY, 0.25);

		// Plans

		this.limitLinkRate = new DefaultPlan(
				new GoalTemplate[] { GoalTemplateFactory.hasBeliefOfTypeWithValue(AttackPrevented.class, Boolean.TRUE),
						GoalTemplateFactory.hasBeliefOfTypeWithValue(OverUsage.class, Boolean.FALSE) },
				LimitLinkRate.class);
		PlanRequiredResource prr = new PlanRequiredResource();
		prr.setRequiredResource(Resources.TIME, 5.0);
		prr.setRequiredResource(Resources.NETWORK_AVAILABILITY, 0.6);
		prr.setRequiredResource(Resources.VULNERABILITY, 0.3);
		this.limitLinkRate.putMetadata(PlanRequiredResource.METADATA_NAME, prr);
		this.restoreLinkRate = new DefaultPlan(
				GoalTemplateFactory.hasBeliefOfTypeWithValue(AttackPrevented.class, Boolean.FALSE),
				RestoreLinkRate.class) {
			@Override
			public boolean isContextApplicable(Goal goal) {
				BeliefGoal<AttackPrevented> bg = (BeliefGoal<AttackPrevented>) goal;
				PredicateBelief<LinkRateLimited> linkRateLimited = (PredicateBelief<LinkRateLimited>) getBeliefBase()
						.getBelief(new LinkRateLimited(bg.getBeliefName().getVariable()));
				return (linkRateLimited != null && linkRateLimited.getValue());
			}
		};

		this.analyseLinkStatistics = new DefaultPlan(GoalTemplateFactory.hasBeliefOfType(AnomalousUsage.class),
				AnalyseLinkStatistics.class);
		this.limitIpRate = new DefaultPlan(
				new GoalTemplate[] { GoalTemplateFactory.hasBeliefOfTypeWithValue(Restricted.class, Boolean.TRUE),
						GoalTemplateFactory.hasBeliefOfTypeWithValue(Anomalous.class, Boolean.FALSE) },
				LimitIPRatePlan.class);
		this.restoreIpRate = new DefaultPlan(
				GoalTemplateFactory.hasBeliefOfTypeWithValue(Restricted.class, Boolean.FALSE),
				RestoreIPRatePlan.class) {
			@Override
			public boolean isContextApplicable(Goal goal) {
				BeliefGoal<Restricted> bg = (BeliefGoal<Restricted>) goal;
				PredicateBelief<IpRateLimited> ipRateLimited = (PredicateBelief<IpRateLimited>) getBeliefBase()
						.getBelief(new IpRateLimited(bg.getBeliefName().getVariable()));
				return (ipRateLimited != null && ipRateLimited.getValue());
			}
		};

		this.analyseIpFlows = new DefaultPlan(GoalTemplateFactory.hasBeliefOfType(Benign.class)

				, AnalyseIPFlows.class);
		this.limitFlowRate = new DefaultPlan(
				new GoalTemplate[] { GoalTemplateFactory.hasBeliefOfTypeWithValue(Threat.class, Boolean.FALSE) },
				LimitFlowRatePlan.class) {
			public boolean isContextApplicable(Goal goal) {
				BeliefGoal<Threat> bg = (BeliefGoal<Threat>) goal;
				PredicateBelief<Threat> threat = (PredicateBelief<Threat>) getBeliefBase()
						.getBelief(bg.getBeliefName());
				return (threat != null && threat.getValue());
			};
		};

	}

	private LinkMonitor getLinkMonitor() {
		return (LinkMonitor) router.getValue().getRole(Role.LINK_MONITOR);
	}

	private RateLimiter getRateLimiter() {
		return (RateLimiter) router.getValue().getRole(Role.RATE_LIMITER);
	}

	private FlowExporter getFlowExporter() {
		return (FlowExporter) router.getValue().getRole(Role.FLOW_EXPORTER);
	}

	private Classifier getClassifier() {
		return (Classifier) router.getValue().getRole(Role.CLASSIFIER);
	}

	private AnomalyDetection getAnomalyDetection() {
		return (AnomalyDetection) router.getValue().getRole(Role.ANOMALY_DETECTION);
	}

	@Override
	public Role getRole() {
		// FIXME
		return Role.LINK_MONITOR;
	}

	@Override
	protected Set<Class<?>> getLowPriorityGoal() {
		Set<Class<?>> lowPriorityGoals = new HashSet<>();
		lowPriorityGoals.add(AnomalousUsage.class);
		lowPriorityGoals.add(Benign.class);
		return lowPriorityGoals;
	}

	class MyGoalGenerationFunction extends PalliativeOptionGenerationFunction {

		private Boolean added = false;

		public MyGoalGenerationFunction() {
			super(BDI2DoSCapability.this);
		}

		@Override
		public void generateGoals(GoalUpdateSet goalUpdateSet) {
			super.generateGoals(goalUpdateSet);

			// Link Monitor
			Set<Belief<?, ?>> overUsageBeliefs = getBeliefBase().getBeliefsByType(OverUsage.class);
			for (Belief<?, ?> belief : overUsageBeliefs) {
				PredicateBelief<OverUsage> overUsage = (PredicateBelief<OverUsage>) belief;
				Link link = overUsage.getName().getVariable();
				if (overUsage.getValue()) {
					PredicateBelief<AnomalousUsage> anomalousUsage = (PredicateBelief<AnomalousUsage>) getBeliefBase()
							.getBelief(new AnomalousUsage(link));
					PredicateBelief<AttackPrevented> attackPrevented = (PredicateBelief<AttackPrevented>) getBeliefBase()
							.getBelief(new AttackPrevented(link));
					if (anomalousUsage == null || anomalousUsage.getValue()) {
						// OverUsage(l) AND !(not AnomalousUsage(l)) -->
						// ~OverUsage(l)
						if (!added) {
							goalUpdateSet.generateGoal(new OverUsageGoal(link, Boolean.FALSE), BDI2DoSCapability.this,
									null);
							log.info("OverUsageGoal added.");
							added = true;
						}
					}
				}
			}

			Set<Belief<?, ?>> attackPreventedBeliefs = getBeliefBase().getBeliefsByType(AttackPrevented.class);
			for (Belief<?, ?> belief : attackPreventedBeliefs) {
				PredicateBelief<AttackPrevented> attackPrevented = (PredicateBelief<AttackPrevented>) belief;
				if (attackPrevented.getValue()) {
					PredicateBelief<AnomalousUsage> anomalousUsage = (PredicateBelief<AnomalousUsage>) getBeliefBase()
							.getBelief(new AnomalousUsage(attackPrevented.getName().getVariable()));
					// AttackPrevented(l) AND not AnomalousUsage(l) --> not
					// AttackPrevented(l)
					if (anomalousUsage != null && !anomalousUsage.getValue()) {
						goal(goalUpdateSet, attackPrevented.getName(), Boolean.FALSE);
					}
				}
			}

			Set<Belief<?, ?>> restrictedBeliefs = getBeliefBase().getBeliefsByType(Restricted.class);
			for (Belief<?, ?> belief : restrictedBeliefs) {
				PredicateBelief<Restricted> restricted = (PredicateBelief<Restricted>) belief;
				if (restricted.getValue()) {
					PredicateBelief<Benign> benign = (PredicateBelief<Benign>) getBeliefBase()
							.getBelief(new Benign(restricted.getName().getVariable()));
					if (benign != null && benign.getValue()) {
						// Restricted(l) AND Benign(l) --> not
						// Restricted(l)
						goal(goalUpdateSet, restricted.getName(), false);
					}
				}
			}

		}
	}

	@Override
	public void goalPerformed(GoalEvent event) {
		if (GoalStatus.ACHIEVED.equals(event.getStatus())) {
			addBelief(((BeliefGoal<?>) event.getGoal()).getOutputBelief());
		}
	}

	@Override
	public void reviewBeliefs() {
		for (Link link : getLinkMonitor().getLinks()) {
			OverUsage overUsage = new OverUsage(link);
			if (getLinkMonitor().isOverUsage(link)) {
				PredicateBelief<OverUsage> overUsageBelief = (PredicateBelief<OverUsage>) getBeliefBase()
						.getBelief(overUsage);
				if (overUsageBelief == null || !overUsageBelief.getValue()) {
					belief(overUsage, true);
					belief(new AnomalousUsage(link), null);
				}
			} else {
				belief(overUsage, false);
				getLinkMonitor().removeLink(link);
			}
		}

		Set<Belief<?, ?>> overUsageCauseBeliefs = getBeliefBase().getBeliefsByType(OverUsageCause.class);
		Iterator<Belief<?, ?>> it = overUsageCauseBeliefs.iterator();
		while (it.hasNext()) {
			BeliefSet<OverUsageCause, Ip> overUsageCause = (BeliefSet<OverUsageCause, Ip>) it.next();
			if (overUsageCause.getValue().isEmpty()) {
				removeBelief(overUsageCause);
			}
			PredicateBelief<AnomalousUsage> anomalousUsage = (PredicateBelief<AnomalousUsage>) getBeliefBase()
					.getBelief(new AnomalousUsage(overUsageCause.getName().getVariable()));
			if (anomalousUsage != null && (anomalousUsage.getValue() == null || !anomalousUsage.getValue())) {
				removeBelief(anomalousUsage);
			}
		}

		Set<Belief<?, ?>> benignBeliefs = getBeliefBase().getBeliefsByType(Benign.class);
		Iterator<Belief<?, ?>> it2 = benignBeliefs.iterator();
		while (it2.hasNext()) {
			PredicateBelief<Benign> benignBelief = (PredicateBelief<Benign>) it2.next();
			if (benignBelief.getValue() == null || benignBelief.getValue()) {
				removeBelief(benignBelief);
			}
		}
	}

	@Override
	public void update(Observable o, Object arg) {
		getMyAgent().restart();
	}

}