smats  0.0.1
Satisfability Modulo Arithmetic Theories Symbols
Loading...
Searching...
No Matches
expression_cell.h
1
7#pragma once
8
9#include <map>
10#include <memory>
11#include <ostream>
12#include <stdexcept>
13#include <unordered_map>
14#include <utility>
15
16#include "smats/symbolic/environment.h"
17#include "smats/symbolic/expression.h"
18#include "smats/symbolic/expression_kind.h"
19#include "smats/symbolic/variable.h"
20#include "smats/symbolic/variables.h"
21#include "smats/util/definitions.h"
22#include "smats/util/hash.hpp"
23
24namespace smats {
25
26template <class T>
27using Substitution = std::unordered_map<Variable, Expression<T>>;
28
29#define PARAMS(...) __VA_ARGS__
30#define NEW_OPERATOR(class_name) \
31 static std::shared_ptr<const class_name<T>> New() { \
32 return std::make_shared<const class_name<T>>(typename ExpressionCell<T>::Private()); \
33 } \
34 explicit class_name(typename ExpressionCell<T>::Private)
35
36#define NEW_OPERATOR_PARAMS(class_name, params, args) \
37 static std::shared_ptr<const class_name<T>> New(params) { \
38 return std::make_shared<const class_name<T>>(typename ExpressionCell<T>::Private(), args); \
39 } \
40 class_name(typename ExpressionCell<T>::Private, params)
41
53template <class T>
54class ExpressionCell : public std::enable_shared_from_this<ExpressionCell<T>> {
55 public:
56 ExpressionCell() = delete;
57 virtual ~ExpressionCell() = default;
58
60 [[nodiscard]] long use_count() const {
61 return std::enable_shared_from_this<ExpressionCell<T>>::shared_from_this().use_count();
62 }
63
65 [[nodiscard]] ExpressionKind kind() const { return kind_; }
66
71 virtual void hash(DelegatingHasher&) const = 0;
72
74 [[nodiscard]] const Variables& variables() const;
75
77 [[nodiscard]] bool is_polynomial() const;
78
80 [[nodiscard]] bool is_expanded() const { return is_expanded_; }
81
83 [[nodiscard]] virtual bool equal_to(const ExpressionCell<T>& o) const = 0;
84
86 [[nodiscard]] virtual bool less(const ExpressionCell<T>& o) const = 0;
87
89 void set_expanded() { is_expanded_ = true; }
90
96 template <template <class> class E>
97 [[nodiscard]] const E<T>& to() const {
98#ifndef NDEBUG
99 if (kind() != E<T>::expression_kind) throw std::runtime_error("ExpressionCell::to(): invalid cast");
100#endif
101 return static_cast<const E<T>&>(*this);
102 }
108 template <template <class> class E>
109 [[nodiscard]] E<T>& to() {
110#ifndef NDEBUG
111 if (kind() != E<T>::expression_kind) throw std::runtime_error("ExpressionCell::to(): invalid cast");
112#endif
113 return static_cast<E<T>&>(*this);
114 }
115
120 [[nodiscard]] Expression<T> to_expression() const {
121 return Expression{std::enable_shared_from_this<ExpressionCell<T>>::shared_from_this()};
122 }
123
129 [[nodiscard]] virtual T evaluate(const Environment<T>& env) const = 0;
130
135 [[nodiscard]] virtual Expression<T> expand() const = 0;
136
144 [[nodiscard]] virtual Expression<T> evaluate_partial(const Environment<T>& env) const = 0;
145
153 [[nodiscard]] virtual Expression<T> substitute(const Substitution<T>& s) const = 0;
154
160 [[nodiscard]] virtual Expression<T> differentiate(const Variable& x) const = 0;
161
167 virtual std::ostream& display(std::ostream& os) const = 0;
168
175 void invalidate_cache();
176
177 protected:
179 struct Private {};
193
194 virtual void compute_variables(std::optional<Variables>& variables) const = 0;
195 virtual void compute_is_polynomial(std::optional<bool>& is_polynomial) const = 0;
196
197 private:
199 mutable std::optional<Variables> variables_;
200 mutable std::optional<bool> is_polynomial_;
201 bool is_expanded_{false};
202};
203
218template <class T>
220 public:
222 [[nodiscard]] const Expression<T>& get_argument() const { return e_; }
223
224 protected:
245 [[nodiscard]] virtual T do_evaluate(T v) const = 0;
246
247 private:
249};
250
264template <class T>
266 public:
267 void hash(DelegatingHasher& hasher) const override;
268 [[nodiscard]] bool equal_to(const ExpressionCell<T>& o) const override;
269 [[nodiscard]] bool less(const ExpressionCell<T>& o) const override;
270 [[nodiscard]] T evaluate(const Environment<T>& env) const override;
272 [[nodiscard]] const Expression<T>& lhs() const { return e1_; }
274 [[nodiscard]] const Expression<T>& rhs() const { return e2_; }
275
276 protected:
291 [[nodiscard]] virtual T do_evaluate(const T& v1, const T& v2) const = 0;
292
293 void compute_variables(std::optional<Variables>& variables) const override;
294 void compute_is_polynomial(std::optional<bool>& is_polynomial) const override;
295
296 private:
299};
300
307template <class T>
309 public:
310 static const ExpressionKind expression_kind = ExpressionKind::Constant;
311
312 NEW_OPERATOR_PARAMS(ExpressionConstant, const T& constant, constant);
313
315 [[nodiscard]] const T& value() const { return value_; }
317 T& m_value();
318
319 void hash(DelegatingHasher& hasher) const override;
320 [[nodiscard]] bool equal_to(const ExpressionCell<T>& o) const override;
321 [[nodiscard]] bool less(const ExpressionCell<T>& o) const override;
322
323 [[nodiscard]] T evaluate(const Environment<T>& env) const override;
324 [[nodiscard]] Expression<T> expand() const override;
325 [[nodiscard]] Expression<T> evaluate_partial(const Environment<T>& env) const override;
326 [[nodiscard]] Expression<T> substitute(const Substitution<T>& s) const override;
327 [[nodiscard]] Expression<T> differentiate(const Variable& x) const override;
328 std::ostream& display(std::ostream& os) const override;
329
330 private:
331 const T value_;
332
333 void compute_variables(std::optional<Variables>& variables) const override;
334 void compute_is_polynomial(std::optional<bool>& is_polynomial) const override;
335};
336
343template <class T>
344class ExpressionVar : public ExpressionCell<T> {
345 public:
346 static const ExpressionKind expression_kind = ExpressionKind::Var;
347
348 NEW_OPERATOR_PARAMS(ExpressionVar, Variable v, v);
349
351 [[nodiscard]] const Variable& variable() const { return var_; }
352
353 void hash(DelegatingHasher& hasher) const override;
354 [[nodiscard]] bool equal_to(const ExpressionCell<T>& o) const override;
355 [[nodiscard]] bool less(const ExpressionCell<T>& o) const override;
356
357 [[nodiscard]] T evaluate(const Environment<T>& env) const override;
358 [[nodiscard]] Expression<T> expand() const override;
359 [[nodiscard]] Expression<T> evaluate_partial(const Environment<T>& env) const override;
360 [[nodiscard]] Expression<T> substitute(const Substitution<T>& s) const override;
361 [[nodiscard]] Expression<T> differentiate(const Variable& x) const override;
362 std::ostream& display(std::ostream& os) const override;
363
364 private:
366
367 void compute_variables(std::optional<Variables>& variables) const override;
368 void compute_is_polynomial(std::optional<bool>& is_polynomial) const override;
369};
370
377template <class T>
378class ExpressionNaN : public ExpressionCell<T> {
379 public:
380 static const ExpressionKind expression_kind = ExpressionKind::NaN;
381
382 NEW_OPERATOR(ExpressionNaN);
383
384 void hash(DelegatingHasher& hasher) const override;
385 [[nodiscard]] bool equal_to(const ExpressionCell<T>& o) const override;
386 [[nodiscard]] bool less(const ExpressionCell<T>& o) const override;
387 [[nodiscard]] T evaluate(const Environment<T>& env) const override;
388 [[nodiscard]] Expression<T> expand() const override;
389 [[nodiscard]] Expression<T> evaluate_partial(const Environment<T>& env) const override;
390 [[nodiscard]] Expression<T> substitute(const Substitution<T>& s) const override;
391 [[nodiscard]] Expression<T> differentiate(const Variable& x) const override;
392 std::ostream& display(std::ostream& os) const override;
393
394 private:
395 void compute_variables(std::optional<Variables>& variables) const override;
396 void compute_is_polynomial(std::optional<bool>& is_polynomial) const override;
397};
398
411template <class T>
412class ExpressionAdd : public ExpressionCell<T> {
413 public:
414 using ExpressionMap = std::map<Expression<T>, T>;
415 static const ExpressionKind expression_kind = ExpressionKind::Add;
416
417 NEW_OPERATOR_PARAMS(ExpressionAdd, PARAMS(T constant, ExpressionMap expr_to_coeff_map),
418 PARAMS(constant, expr_to_coeff_map));
419
420 void hash(DelegatingHasher&) const override;
421 [[nodiscard]] bool equal_to(const ExpressionCell<T>& o) const override;
422 [[nodiscard]] bool less(const ExpressionCell<T>& o) const override;
423 [[nodiscard]] T evaluate(const Environment<T>& env) const override;
424 [[nodiscard]] Expression<T> evaluate_partial(const Environment<T>& env) const override;
425 [[nodiscard]] Expression<T> expand() const override;
426 [[nodiscard]] Expression<T> substitute(const Substitution<T>& s) const override;
427 [[nodiscard]] Expression<T> differentiate(const Variable& x) const override;
428 std::ostream& display(std::ostream& os) const override;
430 [[nodiscard]] const T& constant() const { return constant_; }
432 T& m_constant();
433
435 [[nodiscard]] const ExpressionMap& expr_to_coeff_map() const { return expr_to_coeff_map_; }
437 ExpressionMap& m_expr_to_coeff_map();
438
439 private:
440 static Variables extract_variables(const ExpressionMap& expr_to_coeff_map);
441
442 const T constant_;
443 const ExpressionMap expr_to_coeff_map_;
444
445 void compute_variables(std::optional<Variables>& variables) const override;
446 void compute_is_polynomial(std::optional<bool>& is_polynomial) const override;
455 std::ostream& display_term(std::ostream& os, bool print_plus, const T& coeff, const Expression<T>& term) const;
456};
457
469template <class T>
470class ExpressionMul : public ExpressionCell<T> {
471 public:
472 using ExpressionMap = std::map<Expression<T>, Expression<T>>;
473 static const ExpressionKind expression_kind = ExpressionKind::Mul;
474
475 NEW_OPERATOR_PARAMS(ExpressionMul, PARAMS(T constant, ExpressionMap expr_to_coeff_map),
476 PARAMS(constant, expr_to_coeff_map));
477
478 void hash(DelegatingHasher&) const override;
479 [[nodiscard]] bool equal_to(const ExpressionCell<T>& o) const override;
480 [[nodiscard]] bool less(const ExpressionCell<T>& o) const override;
481 [[nodiscard]] T evaluate(const Environment<T>& env) const override;
482 [[nodiscard]] Expression<T> evaluate_partial(const Environment<T>& env) const override;
483 [[nodiscard]] Expression<T> expand() const override;
484 [[nodiscard]] Expression<T> substitute(const Substitution<T>& s) const override;
485 [[nodiscard]] Expression<T> differentiate(const Variable& x) const override;
486 std::ostream& display(std::ostream& os) const override;
488 [[nodiscard]] const T& constant() const { return constant_; }
490 T& m_constant();
491
493 [[nodiscard]] const ExpressionMap& base_to_exponent_map() const { return base_to_exponent_map_; }
495 ExpressionMap& m_base_to_exponent_map();
496
497 private:
498 static Variables extract_variables(const ExpressionMap& base_to_exponent_map);
499
500 const T constant_;
501 const ExpressionMap base_to_exponent_map_;
502
503 void compute_variables(std::optional<Variables>& variables) const override;
504 void compute_is_polynomial(std::optional<bool>& is_polynomial) const override;
505
514 std::ostream& display_term(std::ostream& os, bool print_mul, const Expression<T>& base,
515 const Expression<T>& exponent) const;
516};
517
529template <class T>
531 public:
532 static const ExpressionKind expression_kind = ExpressionKind::Pow;
533 static void check_domain(const T& v1, const T& v2);
534
535 NEW_OPERATOR_PARAMS(ExpressionPow, PARAMS(const Expression<T>& e1, const Expression<T>& e2), PARAMS(e1, e2));
536
537 Expression<T> evaluate_partial(const Environment<T>& env) const override;
538 Expression<T> expand() const override;
539 Expression<T> substitute(const Substitution<T>& s) const override;
540 Expression<T> differentiate(const Variable& x) const override;
541 std::ostream& display(std::ostream& os) const override;
542
543 private:
544 T do_evaluate(const T& v1, const T& v2) const override;
545
546 void compute_is_polynomial(std::optional<bool>& is_polynomial) const override;
547};
548
560template <class T>
562 public:
563 static const ExpressionKind expression_kind = ExpressionKind::Div;
564 static void check_domain(const T& v1, const T& v2);
565
566 NEW_OPERATOR_PARAMS(ExpressionDiv, PARAMS(const Expression<T>& e1, const Expression<T>& e2), PARAMS(e1, e2));
567
568 Expression<T> expand() const override;
569 Expression<T> evaluate_partial(const Environment<T>& env) const override;
570 Expression<T> substitute(const Substitution<T>& s) const override;
571 Expression<T> differentiate(const Variable& x) const override;
572 std::ostream& display(std::ostream& os) const override;
573
574 private:
575 T do_evaluate(const T& v1, const T& v2) const override;
576};
577
578// EXTERNAL_TEMPLATE_INSTANTIATION_NUMERIC(ExpressionCell);
579// EXTERNAL_TEMPLATE_INSTANTIATION_NUMERIC(ExpressionConstant);
580// EXTERNAL_TEMPLATE_INSTANTIATION_NUMERIC(ExpressionVar);
581// EXTERNAL_TEMPLATE_INSTANTIATION_NUMERIC(ExpressionNaN);
582// EXTERNAL_TEMPLATE_INSTANTIATION_NUMERIC(ExpressionAdd);
583// EXTERNAL_TEMPLATE_INSTANTIATION_NUMERIC(ExpressionMul);
584// EXTERNAL_TEMPLATE_INSTANTIATION_NUMERIC(ExpressionPow);
585
586} // namespace smats
Definition expression_cell.h:265
T evaluate(const Environment< T > &env) const override
Definition expression_cell.cpp:206
const Expression< T > & lhs() const
Definition expression_cell.h:272
virtual T do_evaluate(const T &v1, const T &v2) const =0
bool equal_to(const ExpressionCell< T > &o) const override
Definition expression_cell.cpp:194
const Expression< T > e1_
The first argument of the binary expression.
Definition expression_cell.h:297
const Expression< T > e2_
The second argument of the binary expression.
Definition expression_cell.h:298
void hash(DelegatingHasher &hasher) const override
Definition expression_cell.cpp:189
const Expression< T > & rhs() const
Definition expression_cell.h:274
BinaryExpressionCell(ExpressionKind kind, Expression< T > e1, Expression< T > e2, bool is_expanded)
Definition expression_cell.cpp:186
bool less(const ExpressionCell< T > &o) const override
Definition expression_cell.cpp:200
Definition environment.h:45
Definition expression_cell.h:412
Expression< T > differentiate(const Variable &x) const override
Definition expression_cell.cpp:474
ExpressionMap & m_expr_to_coeff_map()
Definition expression_cell.cpp:489
Expression< T > substitute(const Substitution< T > &s) const override
Definition expression_cell.cpp:468
bool equal_to(const ExpressionCell< T > &o) const override
Definition expression_cell.cpp:424
const T & constant() const
Definition expression_cell.h:430
const ExpressionMap & expr_to_coeff_map() const
Definition expression_cell.h:435
const ExpressionMap expr_to_coeff_map_
Map from expressions to their coefficients.
Definition expression_cell.h:443
T & m_constant()
Definition expression_cell.cpp:484
void hash(DelegatingHasher &) const override
Definition expression_cell.cpp:404
Expression< T > evaluate_partial(const Environment< T > &env) const override
Definition expression_cell.cpp:462
std::ostream & display(std::ostream &os) const override
Definition expression_cell.cpp:494
T evaluate(const Environment< T > &env) const override
Definition expression_cell.cpp:451
bool less(const ExpressionCell< T > &o) const override
Definition expression_cell.cpp:435
std::ostream & display_term(std::ostream &os, bool print_plus, const T &coeff, const Expression< T > &term) const
Definition expression_cell.cpp:510
Expression< T > expand() const override
Definition expression_cell.cpp:456
const T constant_
Constant term of the addition.
Definition expression_cell.h:442
Definition expression_cell.h:54
virtual Expression< T > evaluate_partial(const Environment< T > &env) const =0
virtual void hash(DelegatingHasher &) const =0
void set_expanded()
Definition expression_cell.h:89
ExpressionKind kind() const
Definition expression_cell.h:65
std::optional< bool > is_polynomial_
Cached information about whether the expression is a polynomial.
Definition expression_cell.h:200
virtual T evaluate(const Environment< T > &env) const =0
virtual Expression< T > substitute(const Substitution< T > &s) const =0
virtual Expression< T > expand() const =0
E< T > & to()
Definition expression_cell.h:109
bool is_expanded_
Whether the expression is already expanded.
Definition expression_cell.h:201
virtual Expression< T > differentiate(const Variable &x) const =0
Expression< T > to_expression() const
Definition expression_cell.h:120
const E< T > & to() const
Definition expression_cell.h:97
virtual bool less(const ExpressionCell< T > &o) const =0
virtual bool equal_to(const ExpressionCell< T > &o) const =0
std::optional< Variables > variables_
Cached variables in the expression.
Definition expression_cell.h:199
bool is_polynomial() const
Definition expression_cell.cpp:161
const ExpressionKind kind_
The kind of the expression.
Definition expression_cell.h:198
void invalidate_cache()
Definition expression_cell.cpp:167
bool is_expanded() const
Definition expression_cell.h:80
virtual std::ostream & display(std::ostream &os) const =0
long use_count() const
Definition expression_cell.h:60
const Variables & variables() const
Definition expression_cell.cpp:155
Definition expression_cell.h:308
T & m_value()
Definition expression_cell.cpp:273
Expression< T > expand() const override
Definition expression_cell.cpp:257
const T value_
Constant value.
Definition expression_cell.h:331
Expression< T > differentiate(const Variable &x) const override
Definition expression_cell.cpp:269
T evaluate(const Environment< T > &env) const override
Definition expression_cell.cpp:253
std::ostream & display(std::ostream &os) const override
Definition expression_cell.cpp:278
bool less(const ExpressionCell< T > &o) const override
Definition expression_cell.cpp:247
const T & value() const
Definition expression_cell.h:315
Expression< T > evaluate_partial(const Environment< T > &env) const override
Definition expression_cell.cpp:261
bool equal_to(const ExpressionCell< T > &o) const override
Definition expression_cell.cpp:241
Expression< T > substitute(const Substitution< T > &s) const override
Definition expression_cell.cpp:265
Definition expression_cell.h:561
Expression< T > evaluate_partial(const Environment< T > &env) const override
Definition expression_cell.cpp:752
Expression< T > substitute(const Substitution< T > &s) const override
Definition expression_cell.cpp:762
T do_evaluate(const T &v1, const T &v2) const override
Definition expression_cell.cpp:756
Expression< T > expand() const override
Definition expression_cell.cpp:742
std::ostream & display(std::ostream &os) const override
Definition expression_cell.cpp:777
Expression< T > differentiate(const Variable &x) const override
Definition expression_cell.cpp:766
Definition expression_cell.h:470
const T constant_
Constant term of the multiplication.
Definition expression_cell.h:500
void hash(DelegatingHasher &) const override
Definition expression_cell.cpp:534
std::ostream & display(std::ostream &os) const override
Definition expression_cell.cpp:647
const ExpressionMap & base_to_exponent_map() const
Definition expression_cell.h:493
Expression< T > expand() const override
Definition expression_cell.cpp:603
std::ostream & display_term(std::ostream &os, bool print_mul, const Expression< T > &base, const Expression< T > &exponent) const
Definition expression_cell.cpp:662
T & m_constant()
Definition expression_cell.cpp:637
Expression< T > evaluate_partial(const Environment< T > &env) const override
Definition expression_cell.cpp:615
Expression< T > differentiate(const Variable &x) const override
Definition expression_cell.cpp:629
T evaluate(const Environment< T > &env) const override
Definition expression_cell.cpp:593
const ExpressionMap base_to_exponent_map_
Map from expressions to their exponent.
Definition expression_cell.h:501
Expression< T > substitute(const Substitution< T > &s) const override
Definition expression_cell.cpp:622
const T & constant() const
Definition expression_cell.h:488
bool equal_to(const ExpressionCell< T > &o) const override
Definition expression_cell.cpp:566
ExpressionMap & m_base_to_exponent_map()
Definition expression_cell.cpp:642
bool less(const ExpressionCell< T > &o) const override
Definition expression_cell.cpp:577
Definition expression_cell.h:378
T evaluate(const Environment< T > &env) const override
Definition expression_cell.cpp:371
Expression< T > evaluate_partial(const Environment< T > &env) const override
Definition expression_cell.cpp:379
bool less(const ExpressionCell< T > &o) const override
Definition expression_cell.cpp:366
Expression< T > differentiate(const Variable &x) const override
Definition expression_cell.cpp:387
bool equal_to(const ExpressionCell< T > &o) const override
Definition expression_cell.cpp:361
Expression< T > expand() const override
Definition expression_cell.cpp:375
Expression< T > substitute(const Substitution< T > &s) const override
Definition expression_cell.cpp:383
std::ostream & display(std::ostream &os) const override
Definition expression_cell.cpp:391
void hash(DelegatingHasher &hasher) const override
Definition expression_cell.cpp:347
Definition expression_cell.h:530
T do_evaluate(const T &v1, const T &v2) const override
Definition expression_cell.cpp:730
Expression< T > expand() const override
Definition expression_cell.cpp:689
Expression< T > evaluate_partial(const Environment< T > &env) const override
Definition expression_cell.cpp:697
Expression< T > differentiate(const Variable &x) const override
Definition expression_cell.cpp:710
std::ostream & display(std::ostream &os) const override
Definition expression_cell.cpp:714
Expression< T > substitute(const Substitution< T > &s) const override
Definition expression_cell.cpp:701
Definition expression_cell.h:344
bool less(const ExpressionCell< T > &o) const override
Definition expression_cell.cpp:309
bool equal_to(const ExpressionCell< T > &o) const override
Definition expression_cell.cpp:303
std::ostream & display(std::ostream &os) const override
Definition expression_cell.cpp:337
Expression< T > expand() const override
Definition expression_cell.cpp:319
Expression< T > substitute(const Substitution< T > &s) const override
Definition expression_cell.cpp:328
Expression< T > evaluate_partial(const Environment< T > &env) const override
Definition expression_cell.cpp:323
Expression< T > differentiate(const Variable &x) const override
Definition expression_cell.cpp:333
T evaluate(const Environment< T > &env) const override
Definition expression_cell.cpp:315
const Variable var_
Variable contained in the Expression. Cannot be a Boolean variable.
Definition expression_cell.h:365
const Variable & variable() const
Definition expression_cell.h:351
Definition expression.h:185
Definition expression_cell.h:219
const Expression< T > & get_argument() const
Definition expression_cell.h:222
UnaryExpressionCell(ExpressionKind k, Expression< T > e, bool is_expanded)
Definition expression_cell.cpp:176
virtual T do_evaluate(T v) const =0
const Expression< T > e_
The argument of the unary expression.
Definition expression_cell.h:248
Definition variable.h:34
Definition variables.h:27
ExpressionKind enum.
ExpressionKind
Definition expression_kind.h:20
@ Mul
multiplication (*)
@ Pow
power function
@ Constant
constant (double)
Definition hash.hpp:325
Definition expression_cell.h:179