Documentation of CSL
operator.h
Go to the documentation of this file.
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 
22 #ifndef OPERATOR_H_INCLUDED
23 #define OPERATOR_H_INCLUDED
24 
25 #include "abstract.h"
26 #include "commutation.h"
27 #include "utils.h"
28 #include "interface.h"
29 #include "literal.h"
30 #include "numerical.h"
31 
32 namespace csl {
33 
37 template<typename T>
38 class Operator: public T{
39 
40  protected:
41 
42  bool empty;
43 
44  public:
45 
46  Operator(): T(), empty(true){}
47 
48  template<typename ...Args>
49  explicit Operator(Args&& ...args)
50  :T(std::forward<Args>(args)...), empty(true){}
51 
52  ~Operator(){};
53 
54  bool getCommutable() const override;
55 
56  bool commutesWith(Expr_info other, int sign = -1) const override;
57 
58  bool isAnOperator() const override;
59 
60  bool isEmpty() const override;
61 
62  void setEmpty(bool t_empty) override;
63 
64  void setOperandPrivate(const Expr& operand, bool leaveEmpty) override;
65 
66  Expr applyOperator(const Expr& expr, bool leaveEmpty=false) const override;
67 
68  std::optional<Expr> expand(bool full = false,
69  bool inplace = false) const override;
70 
71  std::optional<Expr> expand_if(
72  std::function<bool(Expr const&)> const&f,
73  bool full = false,
74  bool inplace = false) const override;
75 };
76 
77 #endif
78 
79 #ifndef TEMPLATE_OPERATOR_DEFINED
80 #define TEMPLATE_OPERATOR_DEFINED
81 
82 
83 template<typename T>
84 bool Operator<T>::getCommutable() const
85 {
86  return T::getCommutable()
87  and (not empty and this->getOperand()->getCommutable());
88 }
89 
90 template<typename T>
91 bool Operator<T>::commutesWith(Expr_info other, int sign) const
92 {
93  return T::commutesWith(other, sign)
94  and (sign == -1
95  and (empty or Commutation(this->getOperand().get(), other) == CSL_0)
96  and (not empty or not this->operatorAppliesOn(other)));
97 }
98 
99 template<typename T>
100 bool Operator<T>::isAnOperator() const
101 {
102  return true;
103 }
104 
105 template<typename T>
106 bool Operator<T>::isEmpty() const
107 {
108  return empty;
109 }
110 
111 template<typename T>
112 void Operator<T>::setEmpty(bool t_empty)
113 {
114  empty = t_empty;
115 }
116 
117 template<typename T>
118 void Operator<T>::setOperandPrivate(const Expr& expr, bool leaveEmpty)
119 {
120  this->setOperand(expr);
121  empty = empty and leaveEmpty;
122 }
123 
124 bool pullLeft(csl::vector_expr& argument, size_t pos, size_t& begin);
125 bool pullRight(csl::vector_expr& argument, size_t& pos, size_t& end);
126 void getParts(const csl::vector_expr& argument, size_t begin, size_t end,
127  Expr& left, Expr& mid, Expr& right);
128 
129 template<typename T>
130 Expr Operator<T>::applyOperator(const Expr& expr, bool leaveEmpty) const
131 {
132  if (expr->getPrimaryType() == csl::PrimaryType::Numerical
133  and not empty)
134  return CSL_0;
135 
136  csl::vector_expr foo(0);
137  Expr foo2;
138  Expr res;
139  size_t posDerivative;
140  size_t endDerivative;
141  switch(expr->getType()) {
142  case csl::Type::Sum:
143  foo = expr->getVectorArgument();
144  foo2 = Copy(this);
145  for (auto iter=foo.begin(); iter!=foo.end(); ++iter) {
146  *iter = foo2->applyOperator(*iter,leaveEmpty);
147  }
148 
149  return sum_s(foo);
150  break;
151 
152  case csl::Type::Prod:
153  if (this->getOperand() != CSL_1 and this->getOperand() != CSL_UNDEF) {
154  if (this->getOperand()->getType() == csl::Type::Prod)
155  foo = this->getOperand()->getVectorArgument();
156  else
157  foo.push_back(this->getOperand());
158  }
159  foo.insert(foo.end(),expr->begin(),
160  expr->end());
161  posDerivative = 0;
162  endDerivative = foo.size();
163  for (size_t i = 0; i != endDerivative; ++i) {
164  if (not this->operatorAppliesOn(foo[i].get())) {
165  if (not pullLeft(foo,i,posDerivative))
166  pullRight(foo,i,endDerivative);
167  }
168  }
169  if (posDerivative != 0 or endDerivative != foo.size()) {
170  Expr left, mid, right;
171  getParts(foo, posDerivative, endDerivative, left, mid, right);
172  if (not leaveEmpty and mid->getPrimaryType() == csl::PrimaryType::Numerical)
173  return CSL_0;
174  res = Copy(this);
175  res->setOperandPrivate(mid, leaveEmpty);
176  if (*left != CSL_1 or *right != CSL_1)
177  return prod_s(left, prod_s(Refreshed(res), right));
178  else
179  return Refreshed(res);
180  }
181  res = Copy(this);
182  res->setOperandPrivate(prod_s(foo),leaveEmpty);
183  return res;
184  break;
185 
186  default:
187  if (this->operatorAppliesOn(expr.get())) {
188  res = Copy(this);
189  res->setOperandPrivate(res->getOperand()*expr,leaveEmpty);
190  return res;
191  }
192  else {
193  if (empty and not leaveEmpty)
194  return CSL_0;
195  res = Copy(this);
196  if (*Commutation(res->getOperand(),expr) == CSL_0)
197  return prod_s(expr,res);
198  else
199  return prod_s(res,expr);
200  }
201  }
202 }
203 
204 template<class T>
205 std::optional<Expr> Operator<T>::expand(bool full,
206  bool inplace) const
207 {
208  if (full) {
209  std::optional<Expr> op = this->getOperand()->expand(full, inplace);
210  if (not op)
211  return std::nullopt;
212  Expr copyExpr = this->copy();
213  copyExpr->setOperand(CSL_1);
214  copyExpr->setEmpty(true);
215 
216  return copyExpr->applyOperator(op.value());
217  }
218 
219  return T::expand(full, inplace);
220 }
221 
222 template<class T>
223 std::optional<Expr> Operator<T>::expand_if(
224  std::function<bool(Expr const&)> const& f,
225  bool full,
226  bool inplace) const
227 {
228  if (full) {
229  std::optional<Expr> op = this->getOperand()->expand_if(f, full, inplace);
230  if (not op)
231  return std::nullopt;
232  Expr copyExpr = this->copy();
233  copyExpr->setOperand(CSL_1);
234  copyExpr->setEmpty(true);
235 
236  return copyExpr->applyOperator(op.value());
237  }
238 
239  return T::expand_if(f, full, inplace);
240 }
241 
242 } // End of namespace csl
243 
244 #endif
Expr prod_s(const Expr &leftOperand, const Expr &rightOperand, bool explicitProd=0)
Returns the product of the two operands, applying basic simplifications.
Definition: operations.cpp:2246
const csl::Expr CSL_UNDEF
Constant that is useful in return of non-defined calculations as for example Commutator(): [A...
Definition: literal.h:617
Namespace for csl library.
Definition: abreviation.h:34
Expr Copy(const Abstract *expr)
See Copy(const Expr& expr).
Definition: utils.cpp:98
Root class of the inheritance tree of abstracts.
Definition: abstract.h:76
Expr Refreshed(const Abstract *expr)
See Refreshed(const Expr& expr).
Definition: utils.cpp:129
Base classes for all exprs in the program.
Linear operator O(a*X+b*Y) = a*O(X) + b*O(Y)
Definition: operator.h:38
Expr Commutation(const Expr &A, const Expr &B, int sign=-1)
Returns the result of the (anit-)commutation of A and B. In most cases it returns CSL_0...
Definition: commutation.cpp:27
Expression type/.
Definition: abstract.h:1573