All Downloads are FREE. Search and download functionalities are using the official Maven repository.

de.tlc4b.analysis.DefinitionsSorter Maven / Gradle / Ivy

package de.tlc4b.analysis;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.Hashtable;
import java.util.Iterator;

import de.be4.classicalb.core.parser.analysis.DepthFirstAdapter;
import de.be4.classicalb.core.parser.node.ADefinitionExpression;
import de.be4.classicalb.core.parser.node.AExpressionDefinitionDefinition;
import de.be4.classicalb.core.parser.node.AIdentifierExpression;
import de.be4.classicalb.core.parser.node.APredicateDefinitionDefinition;
import de.be4.classicalb.core.parser.node.ASubstitutionDefinitionDefinition;
import de.be4.classicalb.core.parser.node.Node;
import de.be4.classicalb.core.parser.node.PDefinition;

/**
 * A BDefinitions can depend on another BDefinitions. For the translation to
 * TLA+ the definitions must be sorted.
 * 
 * @author hansen
 */

public class DefinitionsSorter extends DepthFirstAdapter {
	private MachineContext machineContext;
	private Hashtable> dependenciesTable;
	private HashSet current;

	private ArrayList allDefinitions;

	public ArrayList getAllDefinitions() {
		return allDefinitions;
	}

	public DefinitionsSorter(MachineContext machineContext,
			ArrayList allDefinitions) {
		this.machineContext = machineContext;
		dependenciesTable = new Hashtable>();

		for (PDefinition def : allDefinitions) {
			def.apply(this);
		}

		this.allDefinitions = sort(new ArrayList(allDefinitions));

	}

	private ArrayList sort(ArrayList list) {
		ArrayList result = new ArrayList();
		boolean newRun = true;
		while (newRun) {
			newRun = false;
			Iterator itr = list.iterator();
			while (itr.hasNext()) {
				PDefinition def = itr.next();
				if (result.contains(def))
					continue;
				HashSet set = dependenciesTable.get(def);
				if (set.size() == 0) {
					newRun = true;
					result.add(def);

					Node defRef = machineContext.getReferences().get(def);
					if (null != defRef) {
						/*
						 * In this case the definition def is a constant
						 * assignment and reference node of the definition is
						 * the constant itself.
						 */
						removeDef(defRef);
					} else {
						removeDef(def);
					}
					break;
				}
			}
		}

		if (result.size() != list.size()) {
			throw new RuntimeException("Found cyclic Definitions.");
		}
		return result;
	}

	private void removeDef(Node def) {
		Iterator> itr = dependenciesTable.values().iterator();
		while (itr.hasNext()) {
			itr.next().remove(def);
		}
	}

	public void inAExpressionDefinitionDefinition(
			AExpressionDefinitionDefinition node) {
		current = new HashSet();
	}

	public void outAExpressionDefinitionDefinition(
			AExpressionDefinitionDefinition node) {
		dependenciesTable.put(node, current);
		current = null;
	}

	public void inAPredicateDefinitionDefinition(
			APredicateDefinitionDefinition node) {
		current = new HashSet();
	}

	public void outAPredicateDefinitionDefinition(
			APredicateDefinitionDefinition node) {
		dependenciesTable.put(node, current);
		current = null;
	}

	public void inASubstitutionDefinitionDefinition(
			ASubstitutionDefinitionDefinition node) {
		current = new HashSet();
	}

	public void outASubstitutionDefinitionDefinition(
			ASubstitutionDefinitionDefinition node) {
		dependenciesTable.put(node, current);
		current = null;
	}

	public void inADefinitionExpression(ADefinitionExpression node) {

		Node refNode = machineContext.getReferences().get(node);
		/*
		 * If refNode is null, then the whole branch was cloned when a constant
		 * assignment was generated
		 */

		if (null != refNode) {
			current.add(refNode);
		}

	}

	public void inAIdentifierExpression(AIdentifierExpression node) {
		Node identifierRef = machineContext.getReferences().get(node);
		if (identifierRef == null)
			return;

		if (machineContext.getConstants().containsValue(identifierRef)) {
			//current.add(identifierRef);
			return;
		}

		if (machineContext.getReferences().get(identifierRef) instanceof PDefinition) {
			current.add(identifierRef);
		}

	}
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy