Frobby  0.9.5
VarNames.cpp
Go to the documentation of this file.
1 /* Frobby: Software for monomial ideal computations.
2  Copyright (C) 2007 Bjarke Hammersholt Roune (www.broune.com)
3 
4  This program is free software; you can redistribute it and/or modify
5  it under the terms of the GNU General Public License as published by
6  the Free Software Foundation; either version 2 of the License, or
7  (at your option) any later version.
8 
9  This program is distributed in the hope that it will be useful,
10  but WITHOUT ANY WARRANTY; without even the implied warranty of
11  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  GNU General Public License for more details.
13 
14  You should have received a copy of the GNU General Public License
15  along with this program. If not, see http://www.gnu.org/licenses/.
16 */
17 #include "stdinc.h"
18 #include "VarNames.h"
19 
20 #include "error.h"
21 #include "FrobbyStringStream.h"
22 
23 #include <limits>
24 
26 }
27 
28 VarNames::VarNames(size_t varCount) {
29  for (size_t i = 0; i < varCount; ++i) {
31  out << 'x' << (i + 1);
32  addVar(out);
33  }
34 }
35 
37  *this = names;
38 }
39 
41  clear();
42 }
43 
44 bool VarNames::addVar(const string& name) {
45  ASSERT(name != "");
46 
47  pair<VarNameMap::iterator, bool> p =_nameToIndex.insert
48  (make_pair(name, _indexToName.size()));
49  if (!p.second) {
50  ASSERT(contains(name));
51  return false;
52  }
53 
54  try {
55  _indexToName.push_back(&(p.first->first)); // TODO: fix to vector of iters
56  } catch (...) {
57  _nameToIndex.erase(p.first);
58  throw;
59  }
60 
61  if (getVarCount() == invalidIndex)
62  reportError("Too many variable names");
63 
64  ASSERT(contains(name));
65  return true;
66 }
67 
69  const string& name) {
70  if (!addVar(name))
71  reportSyntaxError(in, "The variable " + name + " is declared twice.");
72  ASSERT(contains(name));
73 }
74 
75 bool VarNames::operator<(const VarNames& names) const {
76  return lexicographical_compare(_indexToName.begin(),
77  _indexToName.end(),
78  names._indexToName.begin(),
79  names._indexToName.end(),
80  compareNames);
81 }
82 
83 size_t VarNames::getIndex(const string& name) const {
84  VarNameMap::const_iterator it = _nameToIndex.find(name);
85  if (it == _nameToIndex.end())
86  return invalidIndex;
87  else
88  return it->second;
89 }
90 
91 bool VarNames::contains(const string& name) const {
92  return getIndex(name) != invalidIndex;
93 }
94 
96  VarNames names(getVarCount());
97  return *this == names;
98 }
99 
100 const string& VarNames::getName(size_t index) const {
101  ASSERT(index < _indexToName.size());
102 
103  return *(_indexToName[index]);
104 }
105 
107  _nameToIndex.clear();
108  _indexToName.clear();
109 }
110 
111 bool VarNames::empty() const {
112  return _indexToName.empty();
113 }
114 
116  if (this != &names) {
117  clear();
118 
119  _indexToName.reserve(names.getVarCount());
120 
121  for (size_t var = 0; var < names.getVarCount(); ++var)
122  addVar(names.getName(var));
123  }
124 
125  return *this;
126 }
127 
128 bool VarNames::operator==(const VarNames& names) const {
129  if (getVarCount() != names.getVarCount())
130  return false;
131 
132  for (size_t var = 0; var < getVarCount(); ++var)
133  if (getName(var) != names.getName(var))
134  return false;
135 
136  return true;
137 }
138 
139 bool VarNames::operator!=(const VarNames& names) const {
140  return !operator==(names);
141 }
142 
143 void VarNames::swapVariables(size_t a, size_t b) {
144  ASSERT(a < getVarCount());
145  ASSERT(b < getVarCount());
146 
147  ASSERT(_nameToIndex[*_indexToName[a]] == a);
148  ASSERT(_nameToIndex[*_indexToName[b]] == b);
149 
150  if (a == b)
151  return;
152 
154  _nameToIndex[*_indexToName[a]] = a;
155  _nameToIndex[*_indexToName[b]] = b;
156 
157  ASSERT(_nameToIndex[*_indexToName[a]] == a);
158  ASSERT(_nameToIndex[*_indexToName[b]] == b);
159 }
160 
161 void VarNames::projectVar(size_t index) {
162  ASSERT(index < getVarCount());
163 
164  VarNames names;
165  for (size_t var = 0; var < getVarCount(); ++var)
166  if (var != index)
167  names.addVar(getName(var));
168  *this = names;
169 }
170 
171 void VarNames::toString(string& str) const {
172  str.clear();
173  for (size_t i = 0; i < getVarCount(); ++i) {
174  if (i != 0)
175  str += ", ";
176  str += getName(i);
177  }
178 }
179 
180 void VarNames::print(FILE* file) const {
181  fputs("VarNames(", file);
182  for (size_t i = 0; i < getVarCount(); ++i) {
183  if (i != 0)
184  fputs(", ", file);
185  fprintf(file, "%lu<->\"%s\"", (unsigned long)i, getName(i).c_str());
186  }
187  fputs(")\n", file);
188 }
189 
190 void VarNames::swap(VarNames& names) {
191  _indexToName.swap(names._indexToName);
192  _nameToIndex.swap(names._nameToIndex);
193 }
194 
195 bool VarNames::compareNames(const string* a, const string* b) {
196  return *a < *b;
197 }
A replacement for stringstream.
This class offers an input interface which is more convenient and for some purposes more efficient th...
Definition: Scanner.h:50
Defines the variables of a polynomial ring and facilities IO involving them.
Definition: VarNames.h:40
bool addVar(const string &name)
Adds the variable and returns true if name is not already a variable.
Definition: VarNames.cpp:44
size_t getVarCount() const
Returns the current number of variables.
Definition: VarNames.h:113
const string & getName(size_t index) const
The returned reference can become invalid next time addVar is called.
Definition: VarNames.cpp:100
~VarNames()
Definition: VarNames.cpp:40
static bool compareNames(const string *a, const string *b)
Definition: VarNames.cpp:195
VarNames()
Definition: VarNames.cpp:25
void swap(VarNames &names)
Definition: VarNames.cpp:190
VarNameMap _nameToIndex
Definition: VarNames.h:107
void projectVar(size_t index)
Definition: VarNames.cpp:161
bool operator!=(const VarNames &names) const
Definition: VarNames.cpp:139
void swapVariables(size_t a, size_t b)
Swaps the variables with indexes a and b.
Definition: VarNames.cpp:143
bool namesAreDefault() const
Returns true if the names are x1, x2 and so on.
Definition: VarNames.cpp:95
static const size_t invalidIndex
Returns a fixed variable offset that is always invalid.
Definition: VarNames.h:100
void clear()
Resets the number of variables to zero.
Definition: VarNames.cpp:106
void print(FILE *file) const
Definition: VarNames.cpp:180
vector< const string * > _indexToName
Definition: VarNames.h:108
bool operator<(const VarNames &names) const
This also depends on the order of the names.
Definition: VarNames.cpp:75
size_t getIndex(const string &name) const
Returns VarNames::invalidIndex() if name is not known.
Definition: VarNames.cpp:83
VarNames & operator=(const VarNames &names)
Definition: VarNames.cpp:115
void toString(string &str) const
Definition: VarNames.cpp:171
void addVarSyntaxCheckUnique(const Scanner &in, const string &name)
As addvar, except it reports a syntax error if name is already a variable.
Definition: VarNames.cpp:68
bool empty() const
Returns true if the number of variables is zero.
Definition: VarNames.cpp:111
bool operator==(const VarNames &names) const
Definition: VarNames.cpp:128
bool contains(const string &name) const
Returns true if name is the name of a variable.
Definition: VarNames.cpp:91
void reportSyntaxError(const Scanner &scanner, const string &errorMsg)
Definition: error.cpp:44
void reportError(const string &errorMsg)
Definition: error.cpp:23
void swap(hashtable< _Val, _Key, _HF, _Extract, _EqKey, _All > &__ht1, hashtable< _Val, _Key, _HF, _Extract, _EqKey, _All > &__ht2)
Definition: hashtable.h:740
#define ASSERT(X)
Definition: stdinc.h:86