package com.plectix.simulator.simulator.api.steps; import java.util.List; import com.plectix.simulator.controller.SimulatorResultsData; import com.plectix.simulator.controller.SimulatorStatusInterface; import com.plectix.simulator.io.ConsoleOutputManager; import com.plectix.simulator.io.SimulationDataReader; import com.plectix.simulator.simulationclasses.injections.Injection; import com.plectix.simulator.simulator.SimulationArguments; import com.plectix.simulator.simulator.SimulationClock; import com.plectix.simulator.simulator.SimulationData; import com.plectix.simulator.simulator.SimulationState; import com.plectix.simulator.simulator.Simulator; import com.plectix.simulator.simulator.SimulatorMessage; import com.plectix.simulator.simulator.SimulatorStatus; import com.plectix.simulator.simulator.UpdatesPerformer; import com.plectix.simulator.simulator.SimulationArguments.SimulationType; import com.plectix.simulator.simulator.SimulationArguments.StoryCompressionMode; import com.plectix.simulator.simulator.api.OperationType; import com.plectix.simulator.staticanalysis.Rule; import com.plectix.simulator.staticanalysis.stories.Stories; import com.plectix.simulator.staticanalysis.stories.storage.EventBuilder; import com.plectix.simulator.util.PlxTimer; import com.plectix.simulator.util.Info.InfoType; import com.plectix.simulator.util.io.PlxLogger; public class StoriesComputationOperation extends AbstractOperation<Object> { private final Simulator simulator; private final long events; private final double time; private final StoryCompressionMode mode; private final int iterationsNumber; public StoriesComputationOperation(Simulator simulator) { super(simulator.getSimulationData(), OperationType.STORIES); this.simulator = simulator; SimulationData simulationData = simulator.getSimulationData(); SimulationArguments arguments = simulationData.getSimulationArguments(); this.mode = arguments.getStorifyMode(); this.iterationsNumber = arguments.getIterations(); this.correctSimulationArguments(); if (simulationData.getSimulationArguments().isTime()) { this.events = -1; this.time = arguments.getTimeLimit(); } else { this.events = arguments.getMaxNumberOfEvents(); this.time = -1; simulationData.getConsoleOutputManager().println("*Warning* No time limit."); } } private void correctSimulationArguments() { SimulationArguments simulationArguments = simulator.getSimulationData().getSimulationArguments(); simulationArguments.setSimulationType(SimulationType.STORIFY); simulationArguments.setStorifyFlag(true); simulationArguments.setIterations(iterationsNumber); simulationArguments.setStorifyMode(mode); } protected Object performDry() throws Exception { if (time < 0) { this.computeEventStories(); } else { this.computeTimeStories(); } simulator.getSimulationData().getKappaSystem().getState().refreshSimulationType(SimulationType.STORIFY); return null; } private void computeTimeStories() throws Exception { SimulationClock clock = new SimulationClock(simulator.getSimulationData()); clock.setTimeLimit(time); this.runStories(clock); } private void computeEventStories() throws Exception { SimulationClock clock = new SimulationClock(simulator.getSimulationData()); clock.setEvent(events); this.runStories(clock); } private final void runStories(SimulationClock clock) throws Exception { Object statusLock = simulator.getStatusLock(); SimulationState state = simulator.initializeSimulationState(); final SimulationData simulationData = simulator.getSimulationData(); final SimulatorStatusInterface simulatorStatus = simulator.getStatus(); final SimulatorResultsData simulatorResultsData = simulator.getSimulatorResultsData(); final PlxLogger logger = simulator.getLogger(); if (simulationData.getKappaSystem().getStories() == null) { throw new RuntimeException("Kappa input contains no story annotations"); } clock.setClockStamp(System.currentTimeMillis()); Stories stories = simulationData.getKappaSystem().getStories(); ConsoleOutputManager consoleOutputManager = simulationData.getConsoleOutputManager(); synchronized (statusLock) { state.setEventsToZero(); } InfoType additionalInfoOutputType = simulationData .getSimulationArguments().getOutputTypeForAdditionalInfo(); consoleOutputManager.addAdditionalInfo(InfoType.INFO, "-Simulation..."); clock.resetBar(); // PlxTimer timerAllStories = new PlxTimer(); // timerAllStories.startTimer(); simulatorStatus.setStatusMessage(SimulatorMessage.STATUS_RUNNING); synchronized (statusLock) { state.setIterationsToZero(); } int seed = simulationData.getSimulationArguments().getSeed(); consoleOutputManager.addAdditionalInfo(InfoType.INFO, "--Seeding random number generator with given seed " + Integer.valueOf(seed).toString()); EventBuilder eventBuilder = new EventBuilder(); while (state.getCurrentIterationNumber() < simulationData.getSimulationArguments() .getIterations()) { // PlxTimer timer = null; // if (additionalInfoOutputType != InfoType.DO_NOT_OUTPUT) { // consoleOutputManager.addAdditionalInfo(InfoType.INFO, // "-Simulation..."); // timer = new PlxTimer(); // timer.startTimer(); // } boolean isEndRules = false; long clash = 0; long currentNumberOfClashes = 0; simulationData.getStoriesAgentTypesStorage().setIteration( state.getCurrentIterationNumber()); while (!clock.isEndSimulation(state, currentNumberOfClashes)) { if (Thread.interrupted()) { // TODO: Do any necessary clean-up and collect data we can // return consoleOutputManager .println("Simulation is interrupted because the thread is cancelled"); simulatorResultsData.setCancelled(true); simulatorStatus.setProgress(1.0); break; } simulationData.getKappaSystem().checkPerturbation(state.getCurrentTime()); simulationData.getKappaSystem().updateRuleActivities(); Rule rule = simulationData.getKappaSystem().getRandomRule(); if (rule == null) { clock.setTimeLimit(state.getCurrentTime()); consoleOutputManager.println("#"); break; } List<Injection> injectionsList = simulationData .getKappaSystem().chooseInjectionsForRuleApplication( rule); if (!rule.hasInfiniteRate()) { synchronized (statusLock) { state.setCurrentTime(state.getCurrentTime() + simulationData.getKappaSystem() .getTimeValue()); } } if (injectionsList != null) { eventBuilder.setNewEvent(state.getCurrentEventNumber(), rule .getRuleId()); currentNumberOfClashes = 0; // what is this?? if (stories.checkRule(rule.getRuleId(), state.getCurrentIterationNumber())) { rule.applyRuleForStories(injectionsList, eventBuilder, simulationData, true); stories.addLastEventToStoryStorifyRule( state.getCurrentIterationNumber(), eventBuilder.getEvent(), state.getCurrentTime()); synchronized (statusLock) { state.incCurrentEventNumber(); } isEndRules = true; consoleOutputManager.println("#"); break; } rule.applyRuleForStories(injectionsList, eventBuilder, simulationData, false); if (!rule.doesNothing()) { stories.addEventToStory(state.getCurrentIterationNumber(), eventBuilder.getEvent()); } synchronized (statusLock) { state.incCurrentEventNumber(); } UpdatesPerformer.doNegativeUpdate(injectionsList); simulationData.getKappaSystem().doPositiveUpdate(rule, injectionsList); } else { clash++; currentNumberOfClashes++; } } // end of simulation here... clock.checkStoriesBar(state.getCurrentIterationNumber()); synchronized (statusLock) { state.setEventsToZero(); } stories.cleaningStory(state.getCurrentIterationNumber()); this.endSimulation(additionalInfoOutputType, isEndRules, logger); if (state.getCurrentIterationNumber() < simulationData .getSimulationArguments().getIterations() - 1) { this.resetSimulationData(); } // check whether the thread is interrupted above or since then... if (simulatorResultsData.isCancelled() || Thread.interrupted()) { // TODO: Do any necessary clean-up and collect data we can // return consoleOutputManager .println("Simulation is interrupted because the thread is cancelled"); simulatorResultsData.setCancelled(true); simulatorStatus.setProgress(1.0); break; } synchronized (statusLock) { state.incCurrentIterationNumber(); } } // end of iteration here... simulatorStatus.setStatusMessage(SimulatorMessage.STATUS_WRAPPING); if (additionalInfoOutputType != InfoType.DO_NOT_OUTPUT) { consoleOutputManager.println("#"); this.endSimulation(InfoType.OUTPUT, false, logger); } PlxTimer mergeTimer = new PlxTimer(); mergeTimer.startTimer(); endMerge(mergeTimer); } private final void resetSimulationData() throws Exception { SimulationData simulationData = simulator.getSimulationData(); synchronized (simulator.getStatusLock()) { simulator.getState().setCurrentTime(0); } ConsoleOutputManager consoleOutputManager = simulationData.getConsoleOutputManager(); consoleOutputManager.addAdditionalInfo(InfoType.INFO, "-Reset simulation data."); consoleOutputManager.addAdditionalInfo(InfoType.INFO, "-Initialization..."); simulationData.reset(); this.reCompileKappaInput(); simulator.initializeKappaSystem(); } private final void reCompileKappaInput() throws Exception { SimulationData simulationData = simulator.getSimulationData(); SimulatorStatus status = simulator.getLatestFreezedStatus(); status.setStatusMessage(SimulatorMessage.STATUS_READING_KAPPA); new SimulationDataReader(simulationData).compileKappaFile( simulationData.getKappaInput(), InfoType.INFO); } private final void endSimulation(InfoType outputType, boolean noRulesLeft, PlxLogger logger) { switch (outputType) { case OUTPUT: if (noRulesLeft) { logger.info("end of simulation: there are no active rules"); } else { logger.info("end of simulation: time"); } break; } } private final void endMerge(PlxTimer timer) { SimulationData simulationData = simulator.getSimulationData(); SimulationClock.stopTimer(simulationData, InfoType.OUTPUT, timer, "-Merge stories:"); } @Override protected boolean noNeedToPerform() { return false; } @Override protected Object retrievePreparedResult() { return null; } }