COPASI API  4.16.103
ConverterASTNode.cpp
Go to the documentation of this file.
1 // Copyright (C) 2010 - 2015 by Pedro Mendes, Virginia Tech Intellectual
2 // Properties, Inc., University of Heidelberg, and The University
3 // of Manchester.
4 // All rights reserved.
5 
6 // Copyright (C) 2008 - 2009 by Pedro Mendes, Virginia Tech Intellectual
7 // Properties, Inc., EML Research, gGmbH, University of Heidelberg,
8 // and The University of Manchester.
9 // All rights reserved.
10 
11 // Copyright (C) 2004 - 2007 by Pedro Mendes, Virginia Tech Intellectual
12 // Properties, Inc. and EML Research, gGmbH.
13 // All rights reserved.
14 
15 #include <string>
16 #include <iostream>
17 #include "sbml/util/List.h"
18 #include "sbml/common/libsbml-config-common.h"
19 
20 #include "ConverterASTNode.h"
21 
22 #ifndef LIBSBML_USE_LEGACY_MATH
23 
24 /**
25  * Standard constructor
26  */
28 {};
29 
30 /**
31  * Extension of the ASTNode class from libsbml. This class extends the original
32  * ASTNode by some functions to manipulate the children of a node.
33  */
34 
35 /**
36  * Sets the list of children to the one given as argument. The list is not
37  * copied.
38  */
39 void ConverterASTNode::setChildren(List* children)
40 {
41  if (mNumber != NULL)
42  {
43  return; // cannot add children to a number type astnode
44  }
45  else if (mFunction != NULL)
46  {
47  unsigned int size = mFunction->getNumChildren();
48 
49  for (unsigned int i = mFunction->getNumChildren(); i > 0; i--)
50  {
51  mFunction->removeChild(i - 1);
52  }
53 
54  for (unsigned int i = 0; i < children->getSize(); i++)
55  {
56  mFunction->addChild(static_cast<ASTNode*>(children->get(i)));
57  }
58  }
59 };
60 
61 /**
62  * Constructor that makes a ConverterASTNode from an ASTNode.
63  */
64 ConverterASTNode::ConverterASTNode(const ASTNode &templ): ASTNode(templ.getType())
65 {
66  if (this->getType() == AST_RATIONAL)
67  {
68  setValue(templ.getNumerator(), templ.getDenominator());
69  }
70  else if (this->getType() == AST_REAL)
71  {
72  setValue(templ.getReal());
73  }
74  else if (this->getType() == AST_REAL_E)
75  {
76  setValue(templ.getMantissa(), templ.getExponent());
77  }
78 
79  if (this->getType() == AST_PLUS ||
80  this->getType() == AST_MINUS ||
81  this->getType() == AST_TIMES ||
82  this->getType() == AST_DIVIDE ||
83  this->getType() == AST_POWER)
84  {
85  this->mChar = templ.getCharacter();
86  }
87  else if (this->getType() == AST_INTEGER)
88  {
89  setValue(templ.getInteger());
90  }
91 
92  if ((!this->isOperator()) && (!this->isNumber()) && !isConstant())
93  {
94  this->setName(templ.getName());
95  }
96 
97  unsigned int counter;
98 
99  for (counter = 0; counter < templ.getNumChildren(); counter++)
100  {
101  this->addChild(new ConverterASTNode(*templ.getChild(counter)));
102  }
103 };
104 
105 /**
106  * This function returns true if the node represents a user defined function.
107  */
108 /*
109 bool ConverterASTNode::isUserDefinedFunction(){
110  return (this->getType()==AST_FUNCTION);
111 };
112  */
113 
114 #ifdef COPASI_DEBUG
115 /**
116  * Function to print an ASTNode and its children as a simple tree.
117  * The arguments are the node to be printed and the number of spaces that this
118  * node will be indented.
119  */
120 void ConverterASTNode::printASTNode(const ASTNode* node, unsigned int indent)
121 {
122  std::string spacer = "";
123  unsigned int counter;
124 
125  for (counter = 0; counter < indent; counter++)
126  {
127  spacer += " ";
128  }
129 
130  std::cout << spacer;
131 
132  if (node->isFunction() || node->isName())
133  {
134  if (node->getName() == NULL)
135  std::cout << "emptyName";
136  else
137  std::cout << node->getName();
138  }
139  else if (node->isOperator())
140  {
141  std::cout << node->getCharacter();
142  }
143  else if (node->isInteger())
144  {
145  std::cout << node->getInteger();
146  }
147  else if (node->isReal())
148  {
149  std::cout << node->getReal();
150  }
151  else
152  {
153  std::cout << "[" << node->getType() << "]";
154  }
155 
156  std::cout << std::endl;
157 
158  for (counter = 0; counter < node->getNumChildren(); counter++)
159  {
160  ConverterASTNode::printASTNode(node->getChild(counter), indent + 2);
161  }
162 };
163 #endif // COPASI_DEBUG
164 
165 ASTNode* ConverterASTNode::removeChild(unsigned int index)
166 {
167  ASTNode * removedChild = getChild(index);
168 
169  this->ASTNode::removeChild(index);
170 
171  return removedChild;
172 };
173 
174 /**
175  * Constructor that makes a ConverterASTNode from an ASTNode.
176  */
177 ASTNode* ConverterASTNode::shallowCopy(const ASTNode* pOrig)
178 {
179  ConverterASTNode* pTmp = new ConverterASTNode(*pOrig);
180 
181  while (pTmp->getNumChildren() > 0)
182  {
183  delete pTmp->removeChild(0);
184  }
185 
186  ASTNode* pCopy = pTmp->deepCopy();
187  delete pTmp;
188  return pCopy;
189 };
190 
191 #else
192 
193 /**
194  * Standard constructor
195  */
197 {};
198 
199 /**
200  * Extension of the ASTNode class from libsbml. This class extends the original
201  * ASTNode by some functions to manipulate the children of a node.
202  */
203 
204 /**
205  * Sets the list of children to the one given as argument. The list is not
206  * copied.
207  */
208 void ConverterASTNode::setChildren(List* children)
209 {
210  this->mChildren = children;
211 };
212 
213 void fixNaryRelational(ASTNode& node)
214 {
215  if (!node.isRelational()) return;
216 
217  if (node.getNumChildren() == 2) return;
218 
219  ASTNodeType_t type = node.getType();
220  std::vector<ASTNode*> nodes;
221  node.setType(AST_LOGICAL_AND);
222 
223  for (int i = 1; i < node.getNumChildren(); ++i)
224  {
225  ASTNode *current = new ASTNode(type);
226  current->addChild(node.getChild(i - 1)->deepCopy());
227  current->addChild(node.getChild(i)->deepCopy());
228  nodes.push_back(current);
229  }
230 
231  while (node.getNumChildren() > 0)
232  {
233  delete node.getChild(0);
234  node.removeChild(0);
235  }
236 
237  std::vector<ASTNode*>::iterator it = nodes.begin();
238 
239  while (it != nodes.end())
240  {
241  node.addChild(*it);
242  ++it;
243  }
244 }
245 
246 /**
247  * Constructor that makes a ConverterASTNode from an ASTNode.
248  */
249 ConverterASTNode::ConverterASTNode(const ASTNode &templ): ASTNode(templ.getType())
250 {
251  if (this->getType() == AST_RATIONAL)
252  {
253  this->mDenominator = templ.getDenominator();
254  this->mInteger = templ.getNumerator();
255  }
256  else if (this->getType() == AST_REAL || this->getType() == AST_REAL_E)
257  {
258  this->mExponent = templ.getExponent();
259  this->mReal = templ.getMantissa();
260  }
261 
262  if (templ.getNumChildren() > 2 && (
263  this->getType() == AST_RELATIONAL_EQ ||
264  this->getType() == AST_RELATIONAL_NEQ ||
265  this->getType() == AST_RELATIONAL_GEQ ||
266  this->getType() == AST_RELATIONAL_GT ||
267  this->getType() == AST_RELATIONAL_LEQ ||
268  this->getType() == AST_RELATIONAL_LT))
269  {
270  // reduce to binary
271  //const_cast<ASTNode&>(templ).reduceToBinary();
272  fixNaryRelational(const_cast<ASTNode&>(templ));
273  ASTNode::setType(AST_LOGICAL_AND);
274  }
275 
276  if (this->getType() == AST_PLUS || this->getType() == AST_MINUS || this->getType() == AST_TIMES || this->getType() == AST_DIVIDE || this->getType() == AST_POWER)
277  {
278  this->mChar = templ.getCharacter();
279  }
280  else if (this->getType() == AST_INTEGER)
281  {
282  this->mInteger = templ.getInteger();
283  }
284 
285  if ((!this->isOperator()) && (!this->isNumber()))
286  {
287  this->setName(templ.getName());
288  }
289 
290  unsigned int counter;
291 
292  for (counter = 0; counter < templ.getNumChildren(); counter++)
293  {
294  this->addChild(new ConverterASTNode(*templ.getChild(counter)));
295  }
296 };
297 
298 /**
299  * This function returns true if the node represents a user defined function.
300  */
301 /*
302 bool ConverterASTNode::isUserDefinedFunction(){
303  return (this->getType()==AST_FUNCTION);
304 };
305  */
306 
307 #ifdef COPASI_DEBUG
308 /**
309  * Function to print an ASTNode and its children as a simple tree.
310  * The arguments are the node to be printed and the number of spaces that this
311  * node will be indented.
312  */
313 void ConverterASTNode::printASTNode(const ASTNode* node, unsigned int indent)
314 {
315  std::string spacer = "";
316  unsigned int counter;
317 
318  for (counter = 0; counter < indent; counter++)
319  {
320  spacer += " ";
321  }
322 
323  std::cout << spacer;
324 
325  if (node->isFunction() || node->isName())
326  {
327  std::cout << node->getName();
328  }
329  else if (node->isOperator())
330  {
331  std::cout << node->getCharacter();
332  }
333  else if (node->isInteger())
334  {
335  std::cout << node->getInteger();
336  }
337  else if (node->isReal())
338  {
339  std::cout << node->getReal();
340  }
341  else
342  {
343  std::cout << "[" << node->getType() << "]";
344  }
345 
346  std::cout << std::endl;
347 
348  for (counter = 0; counter < node->getNumChildren(); counter++)
349  {
350  ConverterASTNode::printASTNode(node->getChild(counter), indent + 2);
351  }
352 };
353 #endif // COPASI_DEBUG
354 
355 ASTNode* ConverterASTNode::removeChild(unsigned int index)
356 {
357  return static_cast<ASTNode*>(this->mChildren->remove(index));
358 };
359 
360 /**
361  * Constructor that makes a ConverterASTNode from an ASTNode.
362  */
363 ASTNode* ConverterASTNode::shallowCopy(const ASTNode* pOrig)
364 {
365  ConverterASTNode* pTmp = new ConverterASTNode(*pOrig);
366 
367  while (pTmp->getNumChildren() > 0)
368  {
369  delete pTmp->removeChild(0);
370  }
371 
372  ASTNode* pCopy = pTmp->deepCopy();
373  delete pTmp;
374  return pCopy;
375 };
376 
377 #endif // LIBSBML_USE_LEGACY_MATH
bool isNumber(const std::string &str)
Definition: utility.cpp:75
virtual size_t size() const
void setChildren(List *children)
static ASTNode * shallowCopy(const ASTNode *pOrig)
ASTNode * removeChild(unsigned int index)