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

de.tla2b.translation.BMacroHandler Maven / Gradle / Ivy

There is a newer version: 1.4.0
Show newest version
package de.tla2b.translation;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Hashtable;
import java.util.Set;

import tla2sany.semantic.AssumeNode;
import tla2sany.semantic.ExprNode;
import tla2sany.semantic.ExprOrOpArgNode;
import tla2sany.semantic.FormalParamNode;
import tla2sany.semantic.ModuleNode;
import tla2sany.semantic.OpApplNode;
import tla2sany.semantic.OpDefNode;
import tla2sany.semantic.SymbolNode;
import de.tla2b.analysis.AbstractASTVisitor;
import de.tla2b.analysis.SpecAnalyser;
import de.tla2b.config.ConfigfileEvaluator;

public class BMacroHandler extends AbstractASTVisitor {

	private final Hashtable renamingTable = new Hashtable();

	public BMacroHandler(SpecAnalyser specAnalyser, ConfigfileEvaluator conEval) {
		ModuleNode moduleNode = specAnalyser.getModuleNode();
		ArrayList bDefs = new ArrayList();
		for (int i = 0; i < moduleNode.getOpDefs().length; i++) {
			OpDefNode def = moduleNode.getOpDefs()[i];
			if (specAnalyser.getUsedDefinitions().contains(def)) {
				if (conEval != null
						&& conEval.getConstantOverrideTable()
								.containsValue(def)) {
					continue;
				}
				bDefs.add(def);
			}
		}

		for (OpDefNode opDefNode : bDefs) {
			visitDefinition(opDefNode);
		}

		visitAssumptions(moduleNode.getAssumptions());
	}

	public BMacroHandler() {
	}

	private HashSet definitionParameters;
	private HashSet localVariables;
	private final Hashtable> parameterContext = new Hashtable>();

	@Override
	public void visitDefinition(OpDefNode def) {
		definitionParameters = new HashSet();
		definitionParameters.addAll(Arrays.asList(def.getParams()));
		for (FormalParamNode param : definitionParameters) {
			parameterContext.put(param, new HashSet());
		}
		localVariables = new HashSet();

		visitExprNode(def.getBody());

		definitionParameters = null;
		localVariables = null;
	}

	@Override
	public void visitAssumeNode(AssumeNode assumeNode) {
		definitionParameters = new HashSet();
		localVariables = new HashSet();

		visitExprNode(assumeNode.getAssume());

		definitionParameters = null;
		localVariables = null;

	}

	@Override
	public void visitBuiltInNode(OpApplNode n) {
		switch (getOpCode(n.getOperator().getName())) {
		case OPCODE_rfs:
		case OPCODE_nrfs:
		case OPCODE_fc: // Represents [x \in S |-> e]
		case OPCODE_be: // \E x \in S : P
		case OPCODE_bf: // \A x \in S : P
		case OPCODE_bc: // CHOOSE x \in S: P
		case OPCODE_sso: // $SubsetOf Represents {x \in S : P}
		case OPCODE_soa: // $SetOfAll Represents {e : p1 \in S, p2,p3 \in S2}
		{

			FormalParamNode[][] params = n.getBdedQuantSymbolLists();
			HashSet set = new HashSet();
			for (int i = 0; i < params.length; i++) {
				for (int j = 0; j < params[i].length; j++) {
					FormalParamNode param = params[i][j];
					set.add(param);
				}
			}
			localVariables.addAll(set);
			ExprNode[] in = n.getBdedQuantBounds();
			for (ExprNode exprNode : in) {
				visitExprNode(exprNode);
			}
			ExprOrOpArgNode[] arguments = n.getArgs();
			for (ExprOrOpArgNode exprOrOpArgNode : arguments) {
				visitExprOrOpArgNode(exprOrOpArgNode);
			}
			localVariables.removeAll(set);
			return;
		}
		default: {
			super.visitBuiltInNode(n);
			return;
		}

		}

	}

	private Set getStringSet(Set set) {
		HashSet stringSet = new HashSet();
		for (FormalParamNode formalParamNode : set) {
			stringSet.add(formalParamNode.getName().toString());
		}
		return stringSet;
	}

	private HashSet illegalParams;

	private void addToIllegalParams(Set set) {
		if (illegalParams == null) {
			illegalParams = new HashSet(set);
		} else {
			illegalParams.addAll(set);
		}
	}

	private Set getContextOfParam(FormalParamNode param) {
		Set set = parameterContext.get(param);
		if (set == null) {
			set = new HashSet();
		}
		return set;
	}

	public void visitUserDefinedNode(OpApplNode n) {
		OpDefNode operator = (OpDefNode) n.getOperator();
		FormalParamNode[] params = operator.getParams();

		ExprOrOpArgNode[] arguments = n.getArgs();
		for (int i = 0; i < arguments.length; i++) {
			Set set = getContextOfParam(params[i]);
			addToIllegalParams(set);
			visitExprOrOpArgNode(arguments[i]);
			illegalParams.removeAll(set);
		}
	}

	@Override
	public void visitFormalParamNode(OpApplNode n) {
		FormalParamNode param = (FormalParamNode) n.getOperator();
		if (definitionParameters.contains(param)) {
			parameterContext.get(param).addAll(localVariables);
		}

		hasSymbolAValidName(n);
	}

	public void visitConstantNode(OpApplNode n) {
		hasSymbolAValidName(n);
	}

	public void visitVariableNode(OpApplNode n) {
		hasSymbolAValidName(n);
	}

	private void hasSymbolAValidName(OpApplNode n) {
		SymbolNode symbol = n.getOperator();
		String symbolName = symbol.getName().toString();
		if (illegalParams != null) {
			for (FormalParamNode illegalParam : illegalParams) {
				if (symbolName.equals(illegalParam.getName().toString())) {
					Set illgalNames = getStringSet(illegalParams);
					String newName = incName(symbolName, illgalNames);
					renamingTable.put(illegalParam, newName);
				}
			}
		}
	}

	Set globalNames = new HashSet();

	private Boolean existingName(String name) {
		if (globalNames.contains(name)) {
			return true;
		} else
			return false;
	}

	private String incName(String name, Set tempSet) {
		String res = name;
		for (int i = 1; existingName(res) || tempSet.contains(res); i++) {
			res = name + "_" + i;
		}
		return res;
	}

	public boolean containsSymbolNode(SymbolNode s) {
		return renamingTable.containsKey(s);
	}

	public String getNewName(SymbolNode s) {
		return renamingTable.get(s);
	}

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy