Numworks Epsilon  1.4.1
Graphing Calculator Operating System
dynamic_hierarchy.cpp
Go to the documentation of this file.
2 extern "C" {
3 #include <assert.h>
4 #include <stdlib.h>
5 }
6 
7 namespace Poincare {
8 
10  Expression(),
11  m_operands(nullptr),
12  m_numberOfOperands(0)
13 {
14 }
15 
16 DynamicHierarchy::DynamicHierarchy(const Expression * const * operands, int numberOfOperands, bool cloneOperands) :
17  Expression(),
18  m_numberOfOperands(numberOfOperands)
19 {
20  assert(operands != nullptr);
21  m_operands = new const Expression * [numberOfOperands];
22  for (int i=0; i<numberOfOperands; i++) {
23  assert(operands[i] != nullptr);
24  if (cloneOperands) {
25  m_operands[i] = operands[i]->clone();
26  } else {
27  m_operands[i] = operands[i];
28  }
29  const_cast<Expression *>(m_operands[i])->setParent(this);
30  }
31 }
32 
34  if (m_operands != nullptr) {
35  for (int i = 0; i < m_numberOfOperands; i++) {
36  if (m_operands[i] != nullptr) {
37  delete m_operands[i];
38  }
39  }
40  }
41  delete[] m_operands;
42 }
43 
44 void DynamicHierarchy::addOperands(const Expression * const * operands, int numberOfOperands) {
46  const Expression ** newOperands = new const Expression * [m_numberOfOperands+numberOfOperands];
47  for (int i=0; i<m_numberOfOperands; i++) {
48  newOperands[i] = m_operands[i];
49  }
50  for (int i=0; i<numberOfOperands; i++) {
51  const_cast<Expression *>(operands[i])->setParent(this);
52  newOperands[i+m_numberOfOperands] = operands[i];
53  }
54  delete[] m_operands;
55  m_operands = newOperands;
57 }
58 
60  removeOperand(d, false);
62  d->detachOperands();
63  delete d;
64 }
65 
68 }
69 
70 void DynamicHierarchy::addOperandAtIndex(Expression * operand, int index) {
71  assert(index >= 0 && index <= m_numberOfOperands);
72  const Expression ** newOperands = new const Expression * [m_numberOfOperands+1];
73  int j = 0;
74  for (int i=0; i<=m_numberOfOperands; i++) {
75  if (i == index) {
76  operand->setParent(this);
77  newOperands[i] = operand;
78  } else {
79  newOperands[i] = m_operands[j++];
80  }
81  }
82  delete[] m_operands;
83  m_operands = newOperands;
84  m_numberOfOperands += 1;
85 }
86 
87 void DynamicHierarchy::removeOperand(const Expression * e, bool deleteAfterRemoval) {
88  for (int i=0; i<numberOfOperands(); i++) {
89  if (operand(i) == e) {
90  removeOperandAtIndex(i, deleteAfterRemoval);
91  break;
92  }
93  }
94 }
95 
96 
97 
98 
99 void DynamicHierarchy::sortOperands(ExpressionOrder order, bool canBeInterrupted) {
100  for (int i = numberOfOperands()-1; i > 0; i--) {
101  bool isSorted = true;
102  for (int j = 0; j < numberOfOperands()-1; j++) {
103  /* Warning: Matrix operations are not always commutative (ie,
104  * multiplication) so we never swap 2 matrices. */
105 #if MATRIX_EXACT_REDUCING
106  if (order(operand(j), operand(j+1), canBeInterrupted) > 0 && (!operand(j)->recursivelyMatches(Expression::IsMatrix) || !operand(j+1)->recursivelyMatches(Expression::IsMatrix))) {
107 #else
108  if (order(operand(j), operand(j+1), canBeInterrupted) > 0) {
109 #endif
110  swapOperands(j, j+1);
111  isSorted = false;
112  }
113  }
114  if (isSorted) {
115  return;
116  }
117  }
118 }
119 
121  if (numberOfOperands() == 1) {
122  assert(parent() != nullptr);
123  Expression * o = editableOperand(0);
124  replaceWith(o, true);
125  return o;
126  }
127  return this;
128 }
129 
130 // Private
131 
132 void DynamicHierarchy::removeOperandAtIndex(int i, bool deleteAfterRemoval) {
133  if (deleteAfterRemoval) {
134  delete m_operands[i];
135  } else {
136  const_cast<Expression *>(m_operands[i])->setParent(nullptr);
137  }
139  for (int j=i; j<m_numberOfOperands; j++) {
140  m_operands[j] = m_operands[j+1];
141  }
142 }
143 
144 int DynamicHierarchy::simplificationOrderSameType(const Expression * e, bool canBeInterrupted) const {
145  int m = this->numberOfOperands();
146  int n = e->numberOfOperands();
147  for (int i = 1; i <= m; i++) {
148  // The NULL node is the least node type.
149  if (n < i) {
150  return 1;
151  }
152  int order = SimplificationOrder(this->operand(m-i), e->operand(n-i), canBeInterrupted);
153  if (order != 0) {
154  return order;
155  }
156  }
157  // The NULL node is the least node type.
158  if (n > m) {
159  return -1;
160  }
161  return 0;
162 }
163 
164 int DynamicHierarchy::simplificationOrderGreaterType(const Expression * e, bool canBeInterrupted) const {
165  int m = numberOfOperands();
166  if (m == 0) {
167  return -1;
168  }
169  /* Compare e to last term of hierarchy. */
170  int order = SimplificationOrder(operand(m-1), e, canBeInterrupted);
171  if (order != 0) {
172  return order;
173  }
174  if (m > 1) {
175  return 1;
176  }
177  return 0;
178 }
179 
180 }
void removeOperand(const Expression *e, bool deleteAfterRemoval=true)
void addOperand(Expression *operand)
Expression * parent() const
Definition: expression.h:185
#define assert(e)
Definition: assert.h:9
Expression * replaceWith(Expression *newOperand, bool deleteAfterReplace=true)
Definition: expression.cpp:85
static bool IsMatrix(const Expression *e, Context &context)
Definition: expression.cpp:198
bool recursivelyMatches(ExpressionTest test, Context &context) const
Definition: expression.cpp:161
void addOperands(const Expression *const *operands, int numberOfOperands)
const Expression ** m_operands
virtual Expression * clone() const =0
Expression * editableOperand(int i)
Definition: expression.h:176
void addOperandAtIndex(Expression *operand, int index)
static int SimplificationOrder(const Expression *e1, const Expression *e2, bool canBeInterrupted=false)
Definition: expression.cpp:226
const Expression *const * operands() const override
void mergeOperands(DynamicHierarchy *d)
void setParent(Expression *parent)
Definition: expression.h:186
void swapOperands(int i, int j)
Definition: expression.cpp:139
void sortOperands(ExpressionOrder order, bool canBeInterrupted)
int numberOfOperands() const override
const Expression * operand(int i) const
Definition: expression.cpp:78