<commit_before>package stategraph;

import java.io.BufferedWriter;
import java.io.FileWriter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.Stack;
import lhpn2sbml.parser.ExprTree;
import lhpn2sbml.parser.LHPNFile;

public class StateGraph {
	private HashMap<String, LinkedList<Marking>> stateGraph;
	private LHPNFile lhpn;

	public StateGraph(LHPNFile lhpn) {
		this.lhpn = lhpn;
		stateGraph = new HashMap<String, LinkedList<Marking>>();
		buildStateGraph();
	}

	private void buildStateGraph() {
		ArrayList<String> variables = new ArrayList<String>();
		for (String var : lhpn.getBooleanVars()) {
			variables.add(var);
		}
		boolean[] variableVector = new boolean[variables.size()];
		for (int i = 0; i < variableVector.length; i++) {
			if (lhpn.getInitialVal(variables.get(i)).equals("true")) {
				variableVector[i] = true;
			}
			else {
				variableVector[i] = false;
			}
		}
		ArrayList<String> markedPlaces = new ArrayList<String>();
		HashMap<String, Boolean> places = lhpn.getPlaces();
		for (String place : places.keySet()) {
			if (places.get(place)) {
				markedPlaces.add(place);
			}
		}
		LinkedList<Marking> markings = new LinkedList<Marking>();
		int counter = 0;
		Marking state = new Marking(markedPlaces.toArray(new String[0]), new Marking[0], "S"
				+ counter);
		markings.add(state);
		counter++;
		stateGraph.put(vectorToString(variableVector), markings);
		Stack<Transition> transitionsToFire = new Stack<Transition>();
		for (String transition : lhpn.getTransitionList()) {
			boolean addToStack = true;
			if (lhpn.getPreset(transition).length != 0) {
				for (String place : lhpn.getPreset(transition)) {
					if (!markedPlaces.contains(place)) {
						addToStack = false;
					}
				}
			}
			else {
				addToStack = false;
			}
			if (addToStack) {
				transitionsToFire.push(new Transition(transition, copyArrayList(markedPlaces),
						copyStateVector(variableVector), state));
			}
		}
		while (transitionsToFire.size() != 0) {
			Transition fire = transitionsToFire.pop();
			markedPlaces = fire.getMarkedPlaces();
			variableVector = fire.getVariableVector();
			for (String place : lhpn.getPreset(fire.getTransition())) {
				markedPlaces.remove(place);
			}
			for (String place : lhpn.getPostset(fire.getTransition())) {
				markedPlaces.add(place);
			}
			for (int i = 0; i < variables.size(); i++) {
				if (lhpn.getBoolAssignTree(fire.getTransition(), variables.get(i)) != null) {
					if (evaluateExp(lhpn.getBoolAssignTree(fire.getTransition(), variables.get(i))) == 1) {
						variableVector[i] = true;
					}
					else {
						variableVector[i] = false;
					}
				}
			}
			if (!stateGraph.containsKey(vectorToString(variableVector))) {
				markings = new LinkedList<Marking>();
				state = new Marking(markedPlaces.toArray(new String[0]), new Marking[0], "S"
						+ counter);
				markings.add(state);
				fire.getParent().addNextState(state);
				counter++;
				stateGraph.put(vectorToString(variableVector), markings);
				for (String transition : lhpn.getTransitionList()) {
					boolean addToStack = true;
					if (lhpn.getPreset(transition).length != 0) {
						for (String place : lhpn.getPreset(transition)) {
							if (!markedPlaces.contains(place)) {
								addToStack = false;
							}
						}
					}
					else {
						addToStack = false;
					}
					if (addToStack) {
						transitionsToFire
								.push(new Transition(transition, copyArrayList(markedPlaces),
										copyStateVector(variableVector), state));
					}
				}
			}
			else {
				markings = stateGraph.get(vectorToString(variableVector));
				boolean add = true;
				boolean same = true;
				for (Marking mark : markings) {
					for (String place : mark.getMarkings()) {
						if (!markedPlaces.contains(place)) {
							same = false;
						}
					}
					for (String place : markedPlaces) {
						boolean contains = false;
						for (String place2 : mark.getMarkings()) {
							if (place2.equals(place)) {
								contains = true;
							}
						}
						if (!contains) {
							same = false;
						}
					}
					if (same) {
						add = false;
						fire.getParent().addNextState(mark);
					}
					same = true;
				}
				if (add) {
					state = new Marking(markedPlaces.toArray(new String[0]), new Marking[0], "S"
							+ counter);
					markings.add(state);
					fire.getParent().addNextState(state);
					counter++;
					stateGraph.put(vectorToString(variableVector), markings);
					for (String transition : lhpn.getTransitionList()) {
						boolean addToStack = true;
						if (lhpn.getPreset(transition).length != 0) {
							for (String place : lhpn.getPreset(transition)) {
								if (!markedPlaces.contains(place)) {
									addToStack = false;
								}
							}
						}
						else {
							addToStack = false;
						}
						if (addToStack) {
							transitionsToFire.push(new Transition(transition,
									copyArrayList(markedPlaces), copyStateVector(variableVector),
									state));
						}
					}
				}
			}
		}
	}

	private int evaluateExp(ExprTree[] exprTrees) {
		return 0;
	}

	private ArrayList<String> copyArrayList(ArrayList<String> original) {
		ArrayList<String> copy = new ArrayList<String>();
		for (String element : original) {
			copy.add(element);
		}
		return copy;
	}

	private boolean[] copyStateVector(boolean[] original) {
		boolean[] copy = new boolean[original.length];
		for (int i = 0; i < original.length; i++) {
			copy[i] = original[i];
		}
		return copy;
	}

	private String vectorToString(boolean[] vector) {
		String string = "";
		for (boolean b : vector) {
			if (b) {
				string += "1";
			}
			else {
				string += "0";
			}
		}
		return string;
	}

	public void outputStateGraph(String file) {
		try {
			BufferedWriter out = new BufferedWriter(new FileWriter(file));
			out.write("digraph G {\n");

			for (String state : stateGraph.keySet()) {
				for (Marking m : stateGraph.get(state)) {
					out.write(m.getID() + " [shape=\"ellipse\",label=\"" + state + "\"]\n");
					for (Marking next : m.getNextStates()) {
						out.write(m.getID() + " -> " + next.getID() + "\n");
					}
				}
			}
			out.write("}");
			out.close();
		}
		catch (Exception e) {
			System.err.println("Error outputting state graph as dot file.");
		}
	}

	private class Transition {
		private String transition;
		private boolean[] variableVector;
		private ArrayList<String> markedPlaces;
		private Marking parent;

		private Transition(String transition, ArrayList<String> markedPlaces,
				boolean[] variableVector, Marking parent) {
			this.transition = transition;
			this.markedPlaces = markedPlaces;
			this.variableVector = variableVector;
			this.parent = parent;
		}

		private String getTransition() {
			return transition;
		}

		private ArrayList<String> getMarkedPlaces() {
			return markedPlaces;
		}

		private boolean[] getVariableVector() {
			return variableVector;
		}

		private Marking getParent() {
			return parent;
		}
	}

	private class Marking {
		private String[] markings;
		private Marking[] nextStates;
		private String id;

		private Marking(String[] markings, Marking[] nextStates, String id) {
			this.markings = markings;
			this.nextStates = nextStates;
			this.id = id;
		}

		private String getID() {
			return id;
		}

		private String[] getMarkings() {
			return markings;
		}

		private Marking[] getNextStates() {
			return nextStates;
		}

		private void addNextState(Marking nextState) {
			Marking[] newNextStates = new Marking[nextStates.length + 1];
			for (int i = 0; i < nextStates.length; i++) {
				newNextStates[i] = nextStates[i];
			}
			newNextStates[newNextStates.length - 1] = nextState;
			nextStates = newNextStates;
		}
	}
}<commit_msg>Added pointer to previous states in state graph.<commit_after>package stategraph;

import java.io.BufferedWriter;
import java.io.FileWriter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.Stack;
import lhpn2sbml.parser.ExprTree;
import lhpn2sbml.parser.LHPNFile;

public class StateGraph {
	private HashMap<String, LinkedList<State>> stateGraph;
	private LHPNFile lhpn;

	public StateGraph(LHPNFile lhpn) {
		this.lhpn = lhpn;
		stateGraph = new HashMap<String, LinkedList<State>>();
		buildStateGraph();
	}

	private void buildStateGraph() {
		ArrayList<String> variables = new ArrayList<String>();
		for (String var : lhpn.getBooleanVars()) {
			variables.add(var);
		}
		boolean[] variableVector = new boolean[variables.size()];
		for (int i = 0; i < variableVector.length; i++) {
			if (lhpn.getInitialVal(variables.get(i)).equals("true")) {
				variableVector[i] = true;
			}
			else {
				variableVector[i] = false;
			}
		}
		ArrayList<String> markedPlaces = new ArrayList<String>();
		HashMap<String, Boolean> places = lhpn.getPlaces();
		for (String place : places.keySet()) {
			if (places.get(place)) {
				markedPlaces.add(place);
			}
		}
		LinkedList<State> markings = new LinkedList<State>();
		int counter = 0;
		State state = new State(markedPlaces.toArray(new String[0]), new State[0], "S" + counter);
		markings.add(state);
		counter++;
		stateGraph.put(vectorToString(variableVector), markings);
		Stack<Transition> transitionsToFire = new Stack<Transition>();
		for (String transition : lhpn.getTransitionList()) {
			boolean addToStack = true;
			if (lhpn.getPreset(transition).length != 0) {
				for (String place : lhpn.getPreset(transition)) {
					if (!markedPlaces.contains(place)) {
						addToStack = false;
					}
				}
			}
			else {
				addToStack = false;
			}
			if (addToStack) {
				transitionsToFire.push(new Transition(transition, copyArrayList(markedPlaces),
						copyStateVector(variableVector), state));
			}
		}
		while (transitionsToFire.size() != 0) {
			Transition fire = transitionsToFire.pop();
			markedPlaces = fire.getMarkedPlaces();
			variableVector = fire.getVariableVector();
			for (String place : lhpn.getPreset(fire.getTransition())) {
				markedPlaces.remove(place);
			}
			for (String place : lhpn.getPostset(fire.getTransition())) {
				markedPlaces.add(place);
			}
			for (int i = 0; i < variables.size(); i++) {
				if (lhpn.getBoolAssignTree(fire.getTransition(), variables.get(i)) != null) {
					if (evaluateExp(lhpn.getBoolAssignTree(fire.getTransition(), variables.get(i))) == 1) {
						variableVector[i] = true;
					}
					else {
						variableVector[i] = false;
					}
				}
			}
			if (!stateGraph.containsKey(vectorToString(variableVector))) {
				markings = new LinkedList<State>();
				state = new State(markedPlaces.toArray(new String[0]), new State[0], "S" + counter);
				markings.add(state);
				fire.getParent().addNextState(state);
				counter++;
				stateGraph.put(vectorToString(variableVector), markings);
				for (String transition : lhpn.getTransitionList()) {
					boolean addToStack = true;
					if (lhpn.getPreset(transition).length != 0) {
						for (String place : lhpn.getPreset(transition)) {
							if (!markedPlaces.contains(place)) {
								addToStack = false;
							}
						}
					}
					else {
						addToStack = false;
					}
					if (addToStack) {
						transitionsToFire
								.push(new Transition(transition, copyArrayList(markedPlaces),
										copyStateVector(variableVector), state));
					}
				}
			}
			else {
				markings = stateGraph.get(vectorToString(variableVector));
				boolean add = true;
				boolean same = true;
				for (State mark : markings) {
					for (String place : mark.getMarkings()) {
						if (!markedPlaces.contains(place)) {
							same = false;
						}
					}
					for (String place : markedPlaces) {
						boolean contains = false;
						for (String place2 : mark.getMarkings()) {
							if (place2.equals(place)) {
								contains = true;
							}
						}
						if (!contains) {
							same = false;
						}
					}
					if (same) {
						add = false;
						fire.getParent().addNextState(mark);
					}
					same = true;
				}
				if (add) {
					state = new State(markedPlaces.toArray(new String[0]), new State[0], "S"
							+ counter);
					markings.add(state);
					fire.getParent().addNextState(state);
					counter++;
					stateGraph.put(vectorToString(variableVector), markings);
					for (String transition : lhpn.getTransitionList()) {
						boolean addToStack = true;
						if (lhpn.getPreset(transition).length != 0) {
							for (String place : lhpn.getPreset(transition)) {
								if (!markedPlaces.contains(place)) {
									addToStack = false;
								}
							}
						}
						else {
							addToStack = false;
						}
						if (addToStack) {
							transitionsToFire.push(new Transition(transition,
									copyArrayList(markedPlaces), copyStateVector(variableVector),
									state));
						}
					}
				}
			}
		}
	}

	private int evaluateExp(ExprTree[] exprTrees) {
		return 0;
	}

	public HashMap<String, LinkedList<State>> getStateGraph() {
		return stateGraph;
	}

	private ArrayList<String> copyArrayList(ArrayList<String> original) {
		ArrayList<String> copy = new ArrayList<String>();
		for (String element : original) {
			copy.add(element);
		}
		return copy;
	}

	private boolean[] copyStateVector(boolean[] original) {
		boolean[] copy = new boolean[original.length];
		for (int i = 0; i < original.length; i++) {
			copy[i] = original[i];
		}
		return copy;
	}

	private String vectorToString(boolean[] vector) {
		String string = "";
		for (boolean b : vector) {
			if (b) {
				string += "1";
			}
			else {
				string += "0";
			}
		}
		return string;
	}

	public void outputStateGraph(String file) {
		try {
			BufferedWriter out = new BufferedWriter(new FileWriter(file));
			out.write("digraph G {\n");

			for (String state : stateGraph.keySet()) {
				for (State m : stateGraph.get(state)) {
					out.write(m.getID() + " [shape=\"ellipse\",label=\"" + state + "\"]\n");
					for (State next : m.getNextStates()) {
						out.write(m.getID() + " -> " + next.getID() + "\n");
					}
				}
			}
			out.write("}");
			out.close();
		}
		catch (Exception e) {
			System.err.println("Error outputting state graph as dot file.");
		}
	}

	private class Transition {
		private String transition;
		private boolean[] variableVector;
		private ArrayList<String> markedPlaces;
		private State parent;

		private Transition(String transition, ArrayList<String> markedPlaces,
				boolean[] variableVector, State parent) {
			this.transition = transition;
			this.markedPlaces = markedPlaces;
			this.variableVector = variableVector;
			this.parent = parent;
		}

		private String getTransition() {
			return transition;
		}

		private ArrayList<String> getMarkedPlaces() {
			return markedPlaces;
		}

		private boolean[] getVariableVector() {
			return variableVector;
		}

		private State getParent() {
			return parent;
		}
	}

	public class State {
		private String[] markings;
		private State[] nextStates;
		private State[] prevStates;
		private String id;
		private int color;

		private State(String[] markings, State[] nextStates, String id) {
			this.markings = markings;
			this.nextStates = nextStates;
			prevStates = new State[0];
			this.id = id;
			color = -1;
		}

		private String getID() {
			return id;
		}

		private String[] getMarkings() {
			return markings;
		}

		public State[] getNextStates() {
			return nextStates;
		}

		public State[] getPrevStates() {
			return prevStates;
		}

		public int getColor() {
			return color;
		}

		public void setColor(int color) {
			this.color = color;
		}

		private void addNextState(State nextState) {
			State[] newNextStates = new State[nextStates.length + 1];
			for (int i = 0; i < nextStates.length; i++) {
				newNextStates[i] = nextStates[i];
			}
			newNextStates[newNextStates.length - 1] = nextState;
			nextStates = newNextStates;
			nextState.addPreviousState(this);
		}

		private void addPreviousState(State prevState) {
			State[] newPrevStates = new State[prevStates.length + 1];
			for (int i = 0; i < prevStates.length; i++) {
				newPrevStates[i] = prevStates[i];
			}
			newPrevStates[newPrevStates.length - 1] = prevState;
			nextStates = newPrevStates;
		}
	}
}
{'fraction_non_alphanumeric': 0.13266194206141987, 'fraction_numerical': 0.0034191222180778315, 'mean_word_length': 3.1827873114924596, 'pattern_counts': {'":': 0, '<': 56, '<?xml version=': 0, '>': 49, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1345911', 'n_tokens_mistral': 6586, 'n_tokens_neox': 5084, 'n_words': 1124}