<commit_before>package kr.ac.kaist.se.simulator;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;

/**
 * System of Systems Simulator
 * Created by Junho on 2016-08-01.
 * Output model : System.out.println(Integer.toString(tick) + " "
 * + a.getPerformer() + " " + a + " " + cs.getAccumulatedSoSBenefit());
 */
public final class Simulator {

    private ArrayList<BaseConstituent> csList = null;
    private ArrayList<BaseAction> immediateActions = new ArrayList<>();
    private ArrayList<BaseAction> actions = new ArrayList<>();

    private SIMResult result = null;
    private BaseConstituent manager = null;
    private Environment env = null;

    private int tick;
    private int endTick;

    private ArrayList<Integer> plannedActionTicks; // Raising actions following specific random distribution
    private boolean isPlanned; // Checking the is Planned actions?

    public Simulator(BaseConstituent[] CSs, BaseConstituent manager, Environment env){
        this.csList = new ArrayList<>();
        this.csList.addAll(Arrays.asList(CSs));
        this.manager = manager;
        this.env = env;
        this.tick = 0;
        this.endTick = 0;
        this.isPlanned = false;

    }

    public void setEndTick(int tick){
        this.endTick = tick;
    }

    /**
     * simulate the model, reset the environment and states
     */
    public void execute(){
        this.procedure();
    }

    public void reset(){
        this.result = null;
        this.env.reset();
        this.csList.forEach((CS)->CS.reset());
        if(manager != null)
            manager.reset();
    }

    public SIMResult getResult(){
        return this.result;
    }

    /**
     * Simulation Procedure function from "Simulation and SMC of Logic-Based MAS Models"
     */
    private void procedure(){
        this.tick = 0;
        boolean endCondition = false;

            while(!endCondition){
                actions.clear();

                immediateActions.clear();

                for(BaseConstituent cs : this.csList){ // Get immediate candidate action
                    BaseAction a = cs.step();
                    if(a == null)
                        continue;
                    if(a.getActionType() == BaseAction.TYPE.IMMEDIATE){ // This action is immediate
                        // Immediate action: making a decision
                        // insert to immediateAction set
                        immediateActions.add(a);
                    }else {
                        // insert to normal action set
                        // Normal actions
                        actions.add(a);
                    }
                }

                if(this.manager != null){
                    BaseAction a = this.manager.step();
                    if(a != null){
                        if(a.getActionType() == BaseAction.TYPE.IMMEDIATE) {
                            immediateActions.add(a);
                        }
                        else
                            actions.add(a);
                    }
                }

                Collections.shuffle(immediateActions);
                this.progress(BaseAction.TYPE.IMMEDIATE); // Choose

                this.generateExogenousActions(); // Environment action

                Collections.shuffle(actions);
                this.progress(BaseAction.TYPE.NORMAL);

            endCondition = this.evaluateProperties();
        }
        int SoSBenefit = 0;
        for(BaseConstituent CS : this.csList){
            SoSBenefit += CS.getAccumulatedSoSBenefit();
        }
        this.result = new SIMResult(this.tick, SoSBenefit);
    }

    private void increaseTick(int minimumElapsedTime){
        if(minimumElapsedTime > 0)
            this.tick += minimumElapsedTime;
    }

    private boolean evaluateProperties(){
        /*
         * 1. Check whether is world ended?
         * 1-1. If all CS has the cost which is less than the minimum cost of actions to execute
         *
         */
        boolean verdict = true;
        for(BaseConstituent CS: this.csList){
            if(CS.getStatus() != BaseConstituent.Status.END)
                verdict = false;
        }
        if(this.tick >= endTick){
            verdict = true;
        }
        return verdict;
    }

    private void generateExogenousActions(){
        /*
         * Generate randomly out action
         * Notify to CS that environment generate the actions
         */
        if(this.isPlanned){
            while(this.plannedActionTicks.size() > 0 && this.tick >= this.plannedActionTicks.get(0)){
                env.generateAction();
                env.notifyCS();
                if(this.manager != null)
                    env.notifyManager(this.manager);
                this.plannedActionTicks.remove(0);
            }
        }else{
            env.generateAction();
            env.notifyCS();
        }
    }

    private void progress(BaseAction.TYPE type){
        if(type == BaseAction.TYPE.IMMEDIATE){
            ArrayList<BaseAction> actionList = this.immediateActions;
            // TODO: 2016-10-20 CS기준으로 수정
            for(BaseAction a : actionList){
                if(a.getActionType() == BaseAction.TYPE.IMMEDIATE) {
                    BaseAction selectedAction = a.getPerformer().immediateAction(); // Select action
                    if(selectedAction != null)
                        actions.add(selectedAction);
                }
            }
        }else if(type == BaseAction.TYPE.NORMAL){
            /*
             * 1. Calculate the minimum time to elapse among action list
             * 2. Elapse the time and execute
             * 3. If the remaining time is 0, then update Cost & Benefit
             */
            ArrayList<BaseAction> actionList = this.actions;
            int minimumElapsedTime = -1;
            if(!actionList.isEmpty()){ // If the action list is not empty
                boolean discreteCondition = true;
                for(BaseConstituent CS: this.csList){ // To get all CS are in operation.
                    if(CS.getStatus() != BaseConstituent.Status.OPERATING){
                        discreteCondition = false;
                        break;
                    }
                }
                if(discreteCondition){ // To jump the tick
                    for(BaseAction a : actionList){// Calculate the minimum jump tick
                        if(minimumElapsedTime < a.getRemainingTime())
                            minimumElapsedTime = a.getRemainingTime();
                    }
                }else{ // If any one CS are not in operation, minimum tick will be one
                    minimumElapsedTime = 1;
                }
                // TODO: 2016-10-20 CS 기준으로 수정
                for(BaseAction a: actionList){ // List로 수정하면 이부분 수정해야함..
//                    a.getPerformer().normalAction(minimumElapsedTime);
                    BaseConstituent[] tmpArr = a.getPerformerList().toArray(new BaseConstituent[a.getPerformerList().size()]);
                    for(int i = 0; i < tmpArr.length; i++){
                        // Real normal action happens.
                        tmpArr[i].normalAction(minimumElapsedTime);
                    }
                }
            }else
                minimumElapsedTime = 1;
            increaseTick(minimumElapsedTime);
        }
        if(type == BaseAction.TYPE.IMMEDIATE) {<commit_msg>More optimization<commit_after>package kr.ac.kaist.se.simulator;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;

/**
 * System of Systems Simulator
 * Created by Junho on 2016-08-01.
 * Output model : System.out.println(Integer.toString(tick) + " "
 * + a.getPerformer() + " " + a + " " + cs.getAccumulatedSoSBenefit());
 */
public final class Simulator {

    private ArrayList<BaseConstituent> csList = null;
    private ArrayList<BaseAction> immediateActions = new ArrayList<>();
    private ArrayList<BaseAction> actions = new ArrayList<>();

    private SIMResult result = null;
    private BaseConstituent manager = null;
    private Environment env = null;

    private int tick;
    private int endTick;

    private ArrayList<Integer> plannedActionTicks; // Raising actions following specific random distribution
    private boolean isPlanned; // Checking the is Planned actions?

    public Simulator(BaseConstituent[] CSs, BaseConstituent manager, Environment env){
        this.csList = new ArrayList<>();
        this.csList.addAll(Arrays.asList(CSs));
        this.manager = manager;
        this.env = env;
        this.tick = 0;
        this.endTick = 0;
        this.isPlanned = false;

    }

    public void setEndTick(int tick){
        this.endTick = tick;
    }

    /**
     * simulate the model, reset the environment and states
     */
    public void execute(){
        this.procedure();
    }

    public void reset(){
        this.result = null;
        this.env.reset();
        this.csList.forEach((CS)->CS.reset());
        if(manager != null)
            manager.reset();
    }

    public SIMResult getResult(){
        return this.result;
    }

    /**
     * Simulation Procedure function from "Simulation and SMC of Logic-Based MAS Models"
     */
    private void procedure(){
        this.tick = 0;
        boolean endCondition = false;

            while(!endCondition){
                actions.clear();

                immediateActions.clear();

                for(BaseConstituent cs : this.csList){ // Get immediate candidate action
                    BaseAction a = cs.step();
                    if(a == null)
                        continue;
                    if(a.getActionType() == BaseAction.TYPE.IMMEDIATE){ // This action is immediate
                        // Immediate action: making a decision
                        // insert to immediateAction set
                        immediateActions.add(a);
                    }else {
                        // insert to normal action set
                        // Normal actions
                        actions.add(a);
                    }
                }

                if(this.manager != null){
                    BaseAction a = this.manager.step();
                    if(a != null){
                        if(a.getActionType() == BaseAction.TYPE.IMMEDIATE) {
                            immediateActions.add(a);
                        }
                        else
                            actions.add(a);
                    }
                }

                Collections.shuffle(immediateActions);
                this.progress(BaseAction.TYPE.IMMEDIATE); // Choose

                this.generateExogenousActions(); // Environment action

                Collections.shuffle(actions);
                this.progress(BaseAction.TYPE.NORMAL);

            endCondition = this.evaluateProperties();
        }
        int SoSBenefit = 0;
        for(BaseConstituent CS : this.csList){
            SoSBenefit += CS.getAccumulatedSoSBenefit();
        }
        this.result = new SIMResult(this.tick, SoSBenefit);
    }

    private void increaseTick(int minimumElapsedTime){
        if(minimumElapsedTime > 0)
            this.tick += minimumElapsedTime;
    }

    private boolean evaluateProperties(){
        /*
         * 1. Check whether is world ended?
         * 1-1. If all CS has the cost which is less than the minimum cost of actions to execute
         *
         */
        boolean verdict = true;
        for(BaseConstituent CS: this.csList){
            if(CS.getStatus() != BaseConstituent.Status.END)
                verdict = false;
        }
        if(this.tick >= endTick){
            verdict = true;
        }
        return verdict;
    }

    private void generateExogenousActions(){
        /*
         * Generate randomly out action
         * Notify to CS that environment generate the actions
         */
        if(this.isPlanned){
            while(this.plannedActionTicks.size() > 0 && this.tick >= this.plannedActionTicks.get(0)){
                env.generateAction();
                env.notifyCS();
                if(this.manager != null)
                    env.notifyManager(this.manager);
                this.plannedActionTicks.remove(0);
            }
        }else{
                    env.generateAction();
                    env.notifyCS();
                }
            }

        private void progress(BaseAction.TYPE type){
            if(type == BaseAction.TYPE.IMMEDIATE){
                ArrayList<BaseAction> actionList = this.immediateActions;
                for(BaseAction a : actionList){
                    if(a.getActionType() == BaseAction.TYPE.IMMEDIATE) {
                        BaseAction selectedAction = a.getPerformer().immediateAction(); // Select action
                    if(selectedAction != null)
                        actions.add(selectedAction);
                }
            }
        }else if(type == BaseAction.TYPE.NORMAL){
            /*
             * 1. Calculate the minimum time to elapse among action list
             * 2. Elapse the time and execute
             * 3. If the remaining time is 0, then update Cost & Benefit
             */
            ArrayList<BaseAction> actionList = this.actions;
            int minimumElapsedTime = -1;
            if(!actionList.isEmpty()){ // If the action list is not empty
                boolean discreteCondition = true;
                minimumElapsedTime = 1;
                for(BaseConstituent CS: this.csList){ // To get all CS are in operation.
                    if(CS.getStatus() != BaseConstituent.Status.OPERATING){
                        discreteCondition = false;
                        break;
                    }
                }
                if(discreteCondition){ // To jump the tick
                    for(BaseAction a : actionList){// Calculate the minimum jump tick
                        int rTime = a.getRemainingTime();
                        if(minimumElapsedTime < rTime)
                            minimumElapsedTime = rTime;
                    }
                }
                for(BaseAction a: actionList){ // List로 수정하면 이부분 수정해야함..
//                    a.getPerformer().normalAction(minimumElapsedTime);
                    BaseConstituent[] tmpArr = a.getPerformerList().toArray(new BaseConstituent[a.getPerformerList().size()]);
                    for(int i = 0; i < tmpArr.length; i++){
                        // Real normal action happens.
                        tmpArr[i].normalAction(minimumElapsedTime);
                    }
                }
            }else
                minimumElapsedTime = 1;
            increaseTick(minimumElapsedTime);
        }
        if(type == BaseAction.TYPE.IMMEDIATE) {
{'fraction_non_alphanumeric': 0.09486112974641084, 'fraction_numerical': 0.004964443848114853, 'mean_word_length': 1.5125568852182707, 'pattern_counts': {'":': 0, '<': 25, '<?xml version=': 0, '>': 31, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 2, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '672521', 'n_tokens_mistral': 3918, 'n_tokens_neox': 3684, 'n_words': 907}