Documentation of CSL
replace.h
1 // This file is part of MARTY.
2 //
3 // MARTY is free software: you can redistribute it and/or modify
4 // it under the terms of the GNU General Public License as published by
5 // the Free Software Foundation, either version 3 of the License, or
6 // (at your option) any later version.
7 //
8 // MARTY is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 // GNU General Public License for more details.
12 //
13 // You should have received a copy of the GNU General Public License
14 // along with MARTY. If not, see <https://www.gnu.org/licenses/>.
15 
16 #pragma once
17 
18 #include "abstract.h"
19 #include "index.h"
20 
21 namespace csl {
22 
24 // Expression replacements
26 
27 void Replace(
28  csl::Expr &expr,
29  csl::Expr const &from,
30  csl::Expr const &to
31  );
32 
33 void Replace(
34  csl::Expr &expr,
35  csl::Parent const &from,
36  csl::Parent const &to
37  );
38 
39 void Replace(
40  csl::Expr &expr,
41  csl::Parent const &from,
42  csl::Expr const &to
43  );
44 
45 void Replace(
46  csl::Expr &expr,
47  std::vector<csl::Parent> const &from,
48  std::vector<csl::Parent> const &to
49  );
50 
51 void Replace(
52  csl::Expr &expr,
53  std::vector<csl::Expr> const &from,
54  std::vector<csl::Expr> const &to
55  );
56 
57 void ReplaceIndicial(
58  csl::Expr &expr,
59  std::vector<csl::Expr> const &from,
60  std::vector<csl::Expr> const &to
61  );
62 
63 void Replace(
64  csl::Expr &expr,
65  std::vector<csl::Parent> const &from,
66  std::vector<csl::Expr> const &to,
67  bool refresh = true
68  );
69 
70 template<class T, class U, class Type, class Type2 = Type>
71 struct canDecay {
72  static inline constexpr bool value =
73  std::is_convertible_v<std::decay_t<T>, Type>
74  && std::is_convertible_v<std::decay_t<U>, Type2>;
75 
76 };
77 
78 template<class T, class U, class Type, class Type2 = Type>
79 inline constexpr bool canDecay_v = canDecay<T, U, Type, Type2>::value;
80 
81 // Template non void Replaced instead of Replace
82 // All impossible overloads are defined explicitly to allow other templates
83 // overloads to work. Sad that C++20 is too recent (concepts would have been
84 // much more relevant) than this solution with std::enable_if.
85 template<class T, class U, class ...Params,
86  typename = std::enable_if_t<
87  !csl::canDecay_v<T, U, csl::Index>
88  && !csl::canDecay_v<T, U, csl::IndexStructure>
89  && !csl::canDecay_v<T, U, std::vector<csl::Index>>
90  >
91  >
92 [[nodiscard]]
93 csl::Expr Replaced(
94  csl::Expr const &expr,
95  T &&p1,
96  U &&p2,
97  Params &&...params
98  )
99 {
100  csl::Expr cpy = expr;
101  csl::Replace(
102  cpy,
103  std::forward<T>(p1),
104  std::forward<U>(p2),
105  std::forward<Params>(params)...
106  );
107  return cpy;
108 }
109 
111 // Index replacements
113 
114 [[nodiscard]]
115 csl::Expr Replaced(
116  csl::Expr const &expr,
117  csl::Index const &from,
118  csl::Index const &to,
119  bool refresh = true
120  );
121 
122 inline void Replace(
123  csl::Expr &expr,
124  csl::Index const &from,
125  csl::Index const &to,
126  bool refresh = true
127  )
128 {
129  expr = csl::Replaced(expr, from, to, refresh);
130 }
131 
132 [[nodiscard]]
133 csl::Expr Replaced(
134  csl::Expr const &expr,
135  std::vector<csl::Index> const &from,
136  std::vector<csl::Index> const &to,
137  bool refresh = true
138  );
139 
140 inline void Replace(
141  csl::Expr &expr,
142  std::vector<csl::Index> const &from,
143  std::vector<csl::Index> const &to,
144  bool refresh = true
145  )
146 {
147  expr = csl::Replaced(expr, from, to, refresh);
148 }
149 
150 [[nodiscard]]
151 csl::Expr Replaced(
152  csl::Expr const &expr,
153  csl::IndexStructure const &from,
154  csl::IndexStructure const &to,
155  bool refresh = true
156  );
157 
158 inline void Replace(
159  csl::Expr &expr,
160  csl::IndexStructure const &from,
161  csl::IndexStructure const &to,
162  bool refresh = true
163  )
164 {
165  expr = csl::Replaced(expr, from, to, refresh);
166 }
167 
169 // Abbreviation treatment
171 
182 using replacementRule =
183  std::function<std::optional<csl::Expr>(csl::Expr const&, bool)>;
184 
194 inline auto ruleToPredicate(replacementRule const &rule) {
195  return [&rule](csl::Expr const &expr) -> bool {
196  return bool(rule(expr, true));
197  };
198 }
199 
210 bool hasWeakDependency(
211  csl::Expr const &expr,
212  std::function<bool(csl::Expr const&)> const &predicate
213  );
214 
223  csl::Expr &expr,
224  replacementRule const &rule
225  );
226 
228 // Replacement rules
230 
231 std::optional<csl::Expr> scalarReplacement(
232  csl::Expr const &expr,
233  std::vector<csl::Expr> const &from,
234  std::vector<csl::Expr> const &ccFrom,
235  std::vector<csl::Expr> const &to,
236  bool isPredicate
237  );
238 
239 std::optional<csl::Expr> indicialReplacement(
240  csl::Expr const &expr,
241  std::vector<csl::Expr> const &from,
242  std::vector<csl::Parent_info> const &parentFrom,
243  std::vector<csl::Expr> const &to,
244  bool isPredicate
245  );
246 
247 std::optional<csl::Expr> tensorReplacement(
248  csl::Expr const &expr,
249  std::vector<csl::Parent> const &from,
250  std::vector<csl::Parent> const &to,
251  bool isPredicate
252  );
253 
254 std::optional<csl::Expr> tensorExpressionReplacement(
255  csl::Expr const &expr,
256  std::vector<csl::Parent> const &from,
257  std::vector<csl::Expr> const &to,
258  bool isPredicate
259  );
260 
262 // Helper functions for indicial replacements
264 
265 void ResetDummyIndices(csl::Expr &expr);
266 
267 void ApplyIndices(
268  csl::Expr &expr,
269  csl::IndexStructure const &structure
270  );
271 
272 void ApplyIndices(
273  csl::Expr &expr,
274  csl::IndexStructure const &from,
275  csl::IndexStructure const &to
276  );
277 
278 void renameIndex(
279  csl::Index &index,
280  std::map<csl::Index, csl::Index> &mapping
281  );
282 
283 void RenameIndices(csl::Expr& expr);
284 
285 csl::Expr RenamedIndices(csl::Expr const& expr);
286 
287 void internal_RenameIndices(
288  csl::Expr &expr,
289  std::map<csl::Index, csl::Index> &mapping
290  );
291 
293 // Template helper overloads
295 
296 template<class ParentType,
297  typename = std::enable_if_t<std::is_convertible_v<ParentType, Parent>>
298  >
299 inline void Replace(
300  Expr& expr,
301  std::vector<ParentType> const& t_from,
302  std::vector<ParentType> const& t_to)
303 {
304  std::vector<Parent> from(t_from.size());
305  std::vector<Parent> to(t_to.size());
306  for (size_t i = 0; i != from.size(); ++i)
307  from[i] = t_from[i];
308  for (size_t i = 0; i != to.size(); ++i)
309  to[i] = t_to[i];
310  Replace(expr, from, to);
311 }
312 
313 template<class ParentType,
314  typename = std::enable_if_t<std::is_convertible_v<ParentType, Parent>>
315  >
316 inline void Replace(
317  Expr& expr,
318  std::vector<ParentType> const& t_from,
319  std::vector<csl::Expr> const& to)
320 {
321  std::vector<Parent> from(t_from.size());
322  for (size_t i = 0; i != from.size(); ++i)
323  from[i] = t_from[i];
324  Replace(expr, from, to);
325 }
326 
328 // Functions that try a replacement and keep the
329 // result only if it is simpler than the initial
330 // expression
332 
333 template<class ...Args>
334 Expr Tried(const Expr& expr, Args &&...args)
335 {
336  Expr trial = Replaced(expr, std::forward<Args>(args)...);
337  return (*trial < expr.get()) ? trial : expr;
338 }
339 
340 template<class ...Args>
341 void Try(Expr& expr, Args &&...args)
342 {
343  Expr trial = Replaced(expr, std::forward<Args>(args)...);
344  if (trial < expr)
345  expr = trial;
346 }
347 
348 } // namespace csl
Definition: replace.h:71
Namespace for csl library.
Definition: abreviation.h:34
Definition: parent.h:439
Index object that is used for indicial objects.
Definition: index.h:75
Type
Enum of the different types of Abstract (i.e. list of all possible specializations).
Definition: enum.h:47
auto ruleToPredicate(replacementRule const &rule)
Converts a replacementRule into a predicate.
Definition: replace.h:194
std::function< std::optional< csl::Expr >(csl::Expr const &, bool)> replacementRule
Replacement rule prototype.
Definition: replace.h:183
void applyThroughAbbreviations(csl::Expr &expr, replacementRule const &rule)
Applies a replacement rule thoughout an expression, also entering abbreviations and replacing them if...
Definition: replace.cpp:287
bool hasWeakDependency(csl::Expr const &expr, std::function< bool(csl::Expr const &)> const &predicate)
Search for a true value for a given predicate in an expression, considering also sub-expressions enca...
Definition: replace.cpp:270
Base classes for all exprs in the program.
Manages a std::vector of Index, to be used by an TensorElement.
Definition: index.h:472
Expression type/.
Definition: abstract.h:1573