/******************************************************************************* * Copyright 2014 Felipe Takiyama * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. ******************************************************************************/ package br.usp.poli.takiyama.prv; import java.util.ArrayList; import java.util.Collection; import java.util.List; /** * A name generator for logical variables * @author Felipe Takiyama */ public final class NameGenerator { private static int count = 0; // Substitutions are in the form renamed/old private static Substitution map = Substitution.getInstance(); private NameGenerator() { // enforces non-instantiability } /** * Returns a new logical Variable name. Names generated have the following * format: X{n}, where n is a number starting from 1. * <br> * The specified LogicalVariable is kept in a map so one can retrieve the * old logical variable name later. * * @param old The logical variable to be renamed. * @return The specified logical variable renamed. */ public static LogicalVariable rename(LogicalVariable old) { /* * Discussion * --------------- * I've made LogicalVariable mutable only to rename it and not create * new instances every time renaming is necessary. * The rename method is visible only inside the package, but still... * The code below looks ugly to me. Sounds 'wrong'. */ if (map.contains(old)) { return (LogicalVariable) map.getReplacement(old); } List<Binding> bindingList = map.asList(); count++; String newName = "X" + count; LogicalVariable newVariable = old.rename(newName); Binding bind = Binding.getInstance(newVariable, old); bindingList.add(bind); map = Substitution.getInstance(bindingList); return newVariable; } /** * Returns a substitution that replaces the specified collection of * logical variables with new names. * * @param oldVariables The logical variables to replace * @return a substitution that replaces the specified collection of * logical variables with new names. */ public static Substitution rename(Collection<LogicalVariable> oldVariables) { List<Binding> toRename = new ArrayList<Binding>(oldVariables.size()); List<Binding> toRestore = map.asList(); for (LogicalVariable old : oldVariables) { String newName = getNewName(); LogicalVariable newVariable = old.rename(newName); toRename.add(Binding.getInstance(old, newVariable)); toRestore.add(Binding.getInstance(newVariable, old)); } map = Substitution.getInstance(toRestore); return Substitution.getInstance(toRename); } /** * Returns a new logical variable name. */ private static String getNewName() { count++; return "X" + count; } /** * Resets the count and clears the mapping of logical variables. */ public static void reset() { count = 0; map = Substitution.getInstance(); } /** * Returns the substitution that restores logical variable old names. * @return the substitution that restores logical variable old names. */ public static Substitution getOldNames() { return map; } }