package com.plectix.simulator.simulationclasses.bologna; import java.util.ArrayList; import java.util.List; import com.plectix.simulator.interfaces.ConnectedComponentInterface; import com.plectix.simulator.simulationclasses.injections.Injection; import com.plectix.simulator.simulationclasses.injections.LiftElement; import com.plectix.simulator.staticanalysis.Agent; import com.plectix.simulator.staticanalysis.Rule; import com.plectix.simulator.staticanalysis.Site; /** * This class describes only those reactions, which we should mention * when talking about Bologna method * @author evlasov * */ public final class Reaction { private final Injection firstInjection; private final Injection secondInjection; private final ConnectedComponentInterface firstComponent; private final ConnectedComponentInterface secondComponent; private List<Injection> list; private final ReactionClass type; private final Rule rule; private final Agent agentInFirstComponentToSwap; private final Agent agentInSecondComponentToSwap; /** * Constructor. * @param rule * @param firstInjection * @param secondInjection */ public Reaction(Rule rule, Injection firstInjection, Injection secondInjection) { this.rule = rule; this.firstInjection = firstInjection; this.secondInjection = secondInjection; this.firstComponent = firstInjection.getImageAgent().getConnectedComponent(); this.secondComponent = secondInjection.getImageAgent().getConnectedComponent(); Agent rulesFirstAgent = rule.getLeftHandSide().get(0).getAgents().get(0); Agent rulesSecondAgent = rule.getLeftHandSide().get(1).getAgents().get(0); this.agentInFirstComponentToSwap = this.findSimilarAgent(firstComponent, rulesSecondAgent, firstInjection.getImageAgent()); this.agentInSecondComponentToSwap = this.findSimilarAgent(secondComponent, rulesFirstAgent, secondInjection.getImageAgent()); if (firstComponent.getAgents().contains(secondInjection.getImageAgent())) { type = ReactionClass.UNARY; } else if (agentInFirstComponentToSwap != null) { if (agentInSecondComponentToSwap != null) { type = ReactionClass.BINARY_TWICE_POLYMERIZING; } else { type = ReactionClass.BINARY_POLYMERIZING; } } else if (agentInSecondComponentToSwap != null) { type = ReactionClass.BINARY_POLYMERIZING; } else { type = ReactionClass.BINARY; } } private final Agent findSimilarAgent(ConnectedComponentInterface component, Agent agent, Agent exception) { for (Agent ccAgent : component.getAgents()) { boolean tmp = true; if (agent == null || ccAgent == null) tmp = false; for (Site site : agent.getSites()) { Site solutionSite = ccAgent.getSiteByName(site.getName()); if (solutionSite == null || !site.expandedEqualz(solutionSite, false)) { tmp = false; break; } } if (tmp && ccAgent != exception) { return ccAgent; } } return null; } public final List<Injection> getInjections() { if (list == null) { list = new ArrayList<Injection>(); list.add(this.firstInjection); list.add(this.secondInjection); } return list; } /** * @return <tt>true</tt> if and only if this reaction is polymerizing (see documentation) */ public final boolean isPolymerizing() { return type == ReactionClass.BINARY_POLYMERIZING || type == ReactionClass.BINARY_TWICE_POLYMERIZING; } /** * @return <tt>true</tt> if and only if this reaction is unary (see documentation) */ public final boolean isUnary() { return type == ReactionClass.UNARY; } /** * @return <tt>true</tt> if and only if this reaction is simple binary (see documentation) */ public final boolean isSimpleBinary() { return type == ReactionClass.BINARY; } /** * @return rule, which belongs to this reaction */ public final Rule getRule() { return this.rule; } public final List<Reaction> getSwappedReactions() { List<Reaction> list = new ArrayList<Reaction>(); if (agentInFirstComponentToSwap != null) { for (Site site : agentInFirstComponentToSwap.getSites()) { for (LiftElement liftE : site.getLift()) { // we can compare these for being == if (liftE.getInjection().getConnectedComponent() == rule.getLeftHandSide().get(1)) { list.add(new Reaction(rule, firstInjection, liftE.getInjection())); } } } } if (agentInSecondComponentToSwap != null) { for (Site site : agentInSecondComponentToSwap.getSites()) { for (LiftElement liftE : site.getLift()) { // we can compare these for being == if (liftE.getInjection().getConnectedComponent() == rule.getLeftHandSide().get(0)) { list.add(new Reaction(rule, liftE.getInjection(), secondInjection)); } } } } return list; } }