Orbiter 2022
Combinatorial Objects
syntax_tree_node.cpp
Go to the documentation of this file.
1/*
2 * syntax_tree_node.cpp
3 *
4 * Created on: Feb 16, 2021
5 * Author: betten
6 */
7
8
9
10
11#include "foundations.h"
12
13using namespace std;
14
15
16namespace orbiter {
17namespace layer1_foundations {
18namespace expression_parser {
19
20
22{
23 Tree = NULL;
26
27 f_terminal = false;
28 T = NULL;
29
31
32 nb_nodes = 0;
33 //Nodes = 0L;
34
36 monomial = NULL;
37
39}
40
42{
43
44 if (f_terminal) {
45 delete T;
46 T = 0L;
47 }
48 else {
49 int i;
50
51 for (i = 0; i < nb_nodes; i++) {
52 delete Nodes[i];
53 }
54 if (monomial) {
56 }
57 }
58}
59
60
62{
63 idx = 0;
64
65 f_terminal = false;
66 T = 0L;
67
69
70 nb_nodes = 0;
71 //Nodes = 0L;
72
73}
74
76 syntax_tree_node **Subtrees, int verbose_level)
77{
78 int f_v = (verbose_level >= 1);
79
80 if (f_v) {
81 cout << "syntax_tree_node::split_by_monomials" << endl;
82 cout << "syntax_tree_node::split_by_monomials Node " << idx << endl;
83 }
84 if (f_terminal) {
85 return;
86 }
87 else {
89 if (f_v) {
90 cout << "syntax_tree_node::split_by_monomials checking multiplication node" << endl;
91 }
93 Subtrees[idx] = this;
94 }
95 else {
96 int i;
97
98 if (f_v) {
99 cout << "syntax_tree_node::split_by_monomials splitting subtree" << endl;
100 }
101 for (i = 0; i < nb_nodes; i++) {
102 Nodes[i]->split_by_monomials(Poly, Subtrees, verbose_level);
103 }
104 }
105 }
106}
107
108int syntax_tree_node::is_homogeneous(int &degree, int verbose_level)
109{
110 int f_v = (verbose_level >= 1);
111 int deg, i;
112
113 if (f_v) {
114 cout << "syntax_tree_node::is_homogeneous Node " << idx << endl;
115 }
116 if (f_terminal) {
117 return TRUE;
118 }
119 else {
120 if (type == operation_type_mult) {
121 if (f_v) {
122 cout << "checking multiplication node" << endl;
123 }
124 deg = 0;
125 for (i = 0; i < Tree->managed_variables.size(); i++) {
126 deg += monomial[i];
127 }
128 if (f_v) {
129 cout << "syntax_tree_node::is_homogeneous node " << idx << " has degree " << deg << endl;
130 }
131 if (degree == -1) {
132 degree = deg;
133 if (f_v) {
134 cout << "syntax_tree_node::is_homogeneous node " << idx << " setting degree to " << degree << endl;
135 }
136 }
137 else {
138 if (deg != degree) {
139 if (f_v) {
140 cout << "syntax_tree_node::is_homogeneous node " << idx << " has degree " << deg << " which is different from " << degree << ", so not homogeneous" << endl;
141 }
142 return FALSE;
143 }
144 }
145 return TRUE;
146 }
147 else {
148 int i, ret;
149
150 if (f_v) {
151 cout << "checking subtree" << endl;
152 }
153 ret = TRUE;
154 for (i = 0; i < nb_nodes; i++) {
155 ret = Nodes[i]->is_homogeneous(degree, verbose_level);
156 if (ret == FALSE) {
157 return FALSE;
158 }
159 }
160 return ret;
161 }
162 }
163
164}
165
166void syntax_tree_node::print(std::ostream &ost)
167{
168
169 ost << "Node " << idx << ": ";
170
171 if (f_terminal) {
172 ost << "is terminal" << std::endl;
173 T->print(ost);
174 }
175
176 else {
177 ost << "with " << nb_nodes << " descendants" << std::endl;
178 ost << "f_has_minus = " << f_has_minus << std::endl;
179 int i;
180 for (i = 0; i < nb_nodes; i++) {
181 ost << "Node " << idx << ", descendant " << i << " is node " << Nodes[i]->idx << std::endl;
182 //Nodes[i]->print(ost);
183 }
184 ost << "detailed list:" << std::endl;
185 for (i = 0; i < nb_nodes; i++) {
186 ost << "Node " << idx << ", descendant " << i << " is node " << Nodes[i]->idx << std::endl;
187 Nodes[i]->print(ost);
188 }
189 }
190 if (f_has_monomial) {
192 }
193
194}
195
196
197
198int syntax_tree_node::evaluate(std::map<std::string, std::string> &symbol_table,
199 field_theory::finite_field *F, int verbose_level)
200{
201 int f_v = (verbose_level >= 1);
202 int i;
203 int a, b;
204
205 if (f_v) {
206 cout << "syntax_tree_node::evaluate" << endl;
207 }
208 if (f_terminal) {
209 a = T->evaluate(symbol_table, F, verbose_level);
210 if (f_has_minus) {
211 a = F->negate(a);
212 }
213 }
214 else {
215 if (nb_nodes == 1) {
216 a = Nodes[0]->evaluate(symbol_table, F, verbose_level);
217 if (f_has_minus) {
218 a = F->negate(a);
219 }
220 }
221 else {
222 if (type == operation_type_mult) {
223 a = 1;
224 for (i = 0; i < nb_nodes; i++) {
225 b = Nodes[i]->evaluate(symbol_table, F, verbose_level);
226 a = F->mult(a, b);
227 }
228 if (f_has_minus) {
229 a = F->negate(a);
230 }
231 }
232 else if (type == operation_type_add) {
233 a = 0;
234 for (i = 0; i < nb_nodes; i++) {
235 b = Nodes[i]->evaluate(symbol_table, F, verbose_level);
236 a = F->add(a, b);
237 }
238 }
239 else {
240 cout << "syntax_tree_node::evaluate unknown operation" << endl;
241 exit(1);
242 }
243 }
244 }
245
246 if (f_v) {
247 cout << "syntax_tree_node::evaluate done, value = " << a << endl;
248 }
249 return a;
250}
251
253{
254 int i;
255
256 if (f_terminal) {
257 if (f_has_minus) {
258 ost << "-";
259 }
260 //T->print_expression(ost);
261 T->print_graphviz(ost);
262 }
263
264 else {
265 if (nb_nodes == 1) {
266 if (f_has_minus) {
267 ost << "-";
268 }
269 Nodes[0]->print_expression(ost);
270 }
271 else {
272 ost << "(";
273 if (type == operation_type_mult) {
274 if (f_has_minus) {
275 ost << "-";
276 }
277 for (i = 0; i < nb_nodes; i++) {
278 Nodes[i]->print_expression(ost);
279 if (i < nb_nodes - 1) {
280 ost << "*";
281 }
282 }
283 }
284 else if (type == operation_type_add) {
285 if (f_has_minus) {
286 ost << "-";
287 }
288 for (i = 0; i < nb_nodes; i++) {
289 Nodes[i]->print_expression(ost);
290 if (i < nb_nodes - 1) {
291 ost << "+";
292 }
293 }
294 }
295 else {
296 if (f_has_minus) {
297 ost << "-";
298 }
299 for (i = 0; i < nb_nodes; i++) {
300 Nodes[i]->print_expression(ost);
301 }
302 }
303 ost << ")";
304 }
305 }
306
307}
308
310{
311 if (f_has_minus) {
312 f_has_minus = false;
313 }
314 else {
315 f_has_minus = true;
316 }
317
318}
319
321{
322
323 ost << "Node " << idx << ": ";
324
325 if (f_terminal) {
326 ost << "is terminal" << std::endl;
327 //T->print(ost);
328 }
329
330 else {
331 ost << "with " << nb_nodes << " descendants" << std::endl;
332 int i;
333 for (i = 0; i < nb_nodes; i++) {
334 ost << "Node " << idx << ", descendant " << i << " is node " << Nodes[i]->idx << std::endl;
335 //Nodes[i]->print(ost);
336 }
337 }
338
339}
340
341
342void syntax_tree_node::export_graphviz(std::string &name, std::ostream &ost)
343{
344 ost << "graph " << name << " {" << std::endl;
345
347
348 ost << "}" << std::endl;
349
350}
351
353{
354 //ost << "Node " << idx << " nb_nodes=" << nb_nodes << endl;
355
356 if (f_terminal) {
357 //ost << "Node " << idx << " is terminal node" << endl;
358 ost << idx << " [label=\"";
359 T->print_graphviz(ost);
360 ost << "\" ] ;" << std::endl;
361 }
362 else {
363 int i;
364 ost << idx << " [label=\"";
365
366
367 if (nb_nodes == 1) {
368 ost << "(...)";
369 }
370 else {
371 if (type == operation_type_mult) {
372 ost << "*";
373 }
374 else if (type == operation_type_add) {
375 ost << "+";
376 }
377 else {
378 cout << "syntax_tree_node::export_graphviz_recursion unknown operation" << endl;
379 exit(1);
380 }
381 }
382 ost << "\" ] ;" << std::endl;
383
384
385 for (i = 0; i < nb_nodes; i++) {
386 ost << idx << " -- " << Nodes[i]->idx << std::endl;
387 }
388 for (i = 0; i < nb_nodes; i++) {
389 //ost << "recursing into node " << Nodes[i]->idx << endl;
391 //ost << "recursing into node " << Nodes[i]->idx << " finished" << endl;
392 }
393 }
394
395}
396
397
398
399}}}
400
401
402
int evaluate(std::map< std::string, std::string > &symbol_table, field_theory::finite_field *F, int verbose_level)
int evaluate(std::map< std::string, std::string > &symbol_table, field_theory::finite_field *F, int verbose_level)
void split_by_monomials(ring_theory::homogeneous_polynomial_domain *Poly, syntax_tree_node **Subtrees, int verbose_level)
void export_graphviz(std::string &name, std::ostream &ost)
void print_monomial(std::ostream &ost, int *monomial)
Definition: syntax_tree.cpp:33
homogeneous polynomials of a given degree in a given number of variables over a finite field GF(q)
Definition: ring_theory.h:88
#define FREE_int(p)
Definition: foundations.h:640
#define TRUE
Definition: foundations.h:231
#define FALSE
Definition: foundations.h:234
orbiter_kernel_system::orbiter_session * Orbiter
global Orbiter session
the orbiter library for the classification of combinatorial objects