File: ExNode.hh

package info (click to toggle)
cadabra2 2.4.3.2-2
  • links: PTS, VCS
  • area: main
  • in suites: sid
  • size: 78,732 kB
  • sloc: ansic: 133,450; cpp: 92,064; python: 1,530; javascript: 203; sh: 184; xml: 182; objc: 53; makefile: 51
file content (153 lines) | stat: -rw-r--r-- 5,366 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153

#pragma once

#include "Kernel.hh"
#include "Storage.hh"
#include "IndexIterator.hh"
#include "IndexClassifier.hh"
#include <memory>
#include <pybind11/pybind11.h>

/// ExNode is a combination of an Ex::iterator and an interface which
/// we can use to manipulate the data pointed to by this iterator.
/// In this way, we can use
///
///   for it in ex:
///      ...
///
/// loops and still use 'it' to do things like insertion etc.
/// which requires knowing the Ex::iterator.
///
/// Iterators are much safer than in C++, because they carry the
/// tree modification interface themselves, and can thus compute
/// their next value for any destructive operation.
///
/// Note that ExNode does not really behave like a Python iterator
/// in the strict sense: it does not return copies of nodes in the
/// tree, but rather objects which know how to modify the tree.

class ExNode : public cadabra::IndexClassifier {
	public:
		ExNode(const cadabra::Kernel&, std::shared_ptr<cadabra::Ex>);

		std::shared_ptr<cadabra::Ex>          ex;
		cadabra::Ex::iterator it;

		ExNode& iter();
		ExNode& next();

		ExNode copy() const;

		std::string __str__() const;
		std::string _latex_() const;

		std::string get_name() const;
		void        set_name(std::string);

		/// Create a copy of the Ex pointed to by this iterator.
		cadabra::Ex get_ex() const;
		
		cadabra::str_node::parent_rel_t get_parent_rel() const;
		void                            set_parent_rel(cadabra::str_node::parent_rel_t);

		pybind11::object get_multiplier() const;
		void             set_multiplier(pybind11::object);

		/// Take a child argument out of the node and
		/// add as child of current.
		//      ExNode      unwrap(ExNode child);

		/// Replace the subtree at the current node with the given
		/// expression. Updates the iterator so that it points to the
		/// replacement subtree.
		void        replace(std::shared_ptr<cadabra::Ex> rep);

		/// Insert a subtree as previous sibling of the current node.
		ExNode      insert(std::shared_ptr<cadabra::Ex>    ins);
		ExNode      insert_it(ExNode ins);

		/// Append a subtree as a child. Return an ExNode pointing to the new child.
		ExNode      append_child(std::shared_ptr<cadabra::Ex>);
		ExNode      append_child_it(ExNode ins);

		/// Add an expression to the given node, adding a sum parent if necessary.
		ExNode      add_ex(std::shared_ptr<cadabra::Ex>);

		/// Erase the current node, iterator becomes invalid!
		void        erase();

		/// Get a new iterator which always stays
		/// below the current one.
		ExNode      getitem_string(std::string tag);
		ExNode      getitem_iterator(ExNode);

		/// Set all elements with the indicated tag to the given value.
		void        setitem_string(std::string tag, std::shared_ptr<cadabra::Ex> val);
		void        setitem_iterator(ExNode, std::shared_ptr<cadabra::Ex> val);

		/// Get a new iterator which only iterates over all first-level
		/// terms. If the first-level is not a sum, the iterator will
		/// only return the single node and then end.
		ExNode      terms();

		/// Get a new iterator which only iterates over all first-level
		/// factors. If the first-level is not a product, the iterator will
		/// only return the single node and then end.
		ExNode      factors();

		/// Get a new iterator which only iterates over all first-level indices
		/// (that is, does not iterate over inherited indices; use 'indices' for that).
		ExNode      own_indices();

		/// Get a new iterator which only iterates over all indices (whether direct
		/// or inherited). Uses an index_iterator internally (see its documentation
		/// for details on behaviour).
		ExNode      indices();

		/// Get a new iterator which only iterates over all free indices (whether direct
		/// or inherited). Uses an index_iterator internally (see its documentation
		/// for details on behaviour).
		ExNode      free_indices();

		/// Get a new iterator which only iterates over all first-level
		/// arguments (non-indices).
		ExNode      args();

		/// Get a new iterator which iterates over all first-level
		/// children (a sibling iterator, in other words).
		ExNode      children();

		std::string tag;
		bool        indices_only, args_only, terms_only, factors_only;

		/// Internal function to update the iterator to the next value.
		/// Switches behaviour depending on use_sibling_iterator, use_index_iterator,
		/// indices_only, args_only, terms_only, factors_only;
		void update(bool first);

		cadabra::Ex::iterator         nxtit;
		cadabra::Ex::sibling_iterator sibnxtit;
		cadabra::index_iterator       indnxtit;

		bool                          use_sibling_iterator;
		bool                          use_index_iterator;
		cadabra::Ex::iterator         topit, stopit;

		index_map_t                   ind_free, ind_dummy;
		index_position_map_t          ind_pos_dummy;

	private:
	};


ExNode Ex_iter(std::shared_ptr<cadabra::Ex> ex);
ExNode Ex_top(std::shared_ptr<cadabra::Ex> ex);
bool   Ex_matches(std::shared_ptr<cadabra::Ex> ex, ExNode& other);
bool   Ex_matches_Ex(std::shared_ptr<cadabra::Ex> ex, std::shared_ptr<cadabra::Ex> other);
bool   ExNode_less(ExNode& one, ExNode& two);
bool   ExNode_greater(ExNode& one, ExNode& two);
ExNode Ex_getitem_string(std::shared_ptr<cadabra::Ex> ex, std::string tag);
ExNode Ex_getitem_iterator(std::shared_ptr<cadabra::Ex> ex, ExNode);