Class Expr

Nested Relationships

Nested Types

Inheritance Relationships

Base Types

  • public std::enable_shared_from_this< Expr >

  • public ranges::view_facade< Expr >

Derived Types

Class Documentation

class Expr : public std::enable_shared_from_this<Expr>, public ranges::view_facade<Expr>

Base expression class.

Expr represents the interface needed to form expression trees. Classes that represent expressions should publicly derive from this class. Each Expr on a tree has links to its children Expr objects. The lifetime of Expr objects is expected to be managed by std::shared_ptr . Expr is an Iterable over subexpressions (each of which is an Expr itself). More precisely, Expr meets the SizedIterable concept (see https://raw.githubusercontent.com/ericniebler/range-v3/master/doc/std/D4128.md). Specifically, iterators to subexpressions dereference to ExprPtr. Since Expr is a range, it provides begin/end/etc. that can participate in overloads with other functions in the derived class. Consider a Container class derived from a BaseContainer class:

template <typename T> class Container : public BaseContainer, public Expr
{
  // WARNING: BaseContainer::begin clashes with Expr::begin
  // WARNING: BaseContainer::end clashes with Expr::end
  // etc.
};
There are two possible scenarios:
  • if Container is a container of Expr objects, BaseContainer will iterate over ExprPtr objects already and both ranges will be equivalent; it is sufficient to add using BaseContainer::begin, etc. to Container’s public API.

  • if Container is a container of non-Expr objects, iteration over BaseContainer is likely to be more commonly used in practice, hence again adding using BaseContainer::begin, etc. will suffice. To be able to iterate over subexpression range (in this case it is empty) Expr provides Expr::expr member to cast to Expr:

    Container c(...);
    for(const auto& e: c) {  // iterates over elements of BaseContainer
    }
    for(const auto& e: c.expr()) {  // iterates over subexpressions
    }
    

Subclassed by sequant::NormalOperatorSequence< S >, sequant::Operator< S >, sequant::Operator< void, S >, sequant::Constant, sequant::NormalOperatorSequence< S >, sequant::Operator< S >, sequant::Product, sequant::Sum, sequant::Tensor, sequant::Variable, sequant::mbpt::Operator< void, S >

in-place arithmetic operators

Virtual in-place arithmetic operators to be overridden in expressions for which these make sense.

virtual Expr &operator*=(const Expr &that)

in-place multiply *this by that

Throws:

std::logic_error – if not implemented for this class, or cannot be implemented for the particular that

Returns:

reference to *this

virtual Expr &operator^=(const Expr &that)

in-place non-commutatively-multiply *this by that

Throws:

std::logic_error – if not implemented for this class, or cannot be implemented for the particular that

Returns:

reference to *this

virtual Expr &operator+=(const Expr &that)

in-place add that to *this

Throws:

std::logic_error – if not implemented for this class, or cannot be implemented for the particular that

Returns:

reference to *this

virtual Expr &operator-=(const Expr &that)

in-place subtract that from *this

Throws:

std::logic_error – if not implemented for this class, or cannot be implemented for the particular that

Returns:

reference to *this

Public Types

using range_type = ranges::view_facade<Expr>
using hash_type = std::size_t
using type_id_type = int

Public Functions

Expr() = default
virtual ~Expr() = default
inline bool is_atom() const
Returns:

true if this is a leaf

virtual std::wstring to_latex() const
Returns:

the string representation of this in the LaTeX format

virtual std::wstring to_wolfram() const
Returns:

the string representation of this in the Wolfram Language format

virtual ExprPtr clone() const

Note

- must be overridden in the derived class.

  • the default implementation throws an exception

Returns:

a clone of this object, i.e. an object that is equal to this

inline ExprPtr exprptr_from_this()

like Expr::shared_from_this, but returns ExprPtr

Throws:

std::bad_weak_ptr – if this object is not managed by a shared_ptr

Returns:

a shared_ptr to this object wrapped into ExprPtr

inline ExprPtr exprptr_from_this() const

like Expr::shared_from_this, but returns ExprPtr

Throws:

std::bad_weak_ptr – if this object is not managed by a shared_ptr

Returns:

a shared_ptr to this object wrapped into ExprPtr

inline virtual ExprPtr canonicalize()

Canonicalizes this and returns the biproduct of canonicalization (e.g. phase)

Returns:

the biproduct of canonicalization, or nullptr if no biproduct generated

inline virtual ExprPtr rapid_canonicalize()

Performs approximate, but fast, canonicalization of this and returns the biproduct of canonicalization (e.g. phase) The default is to use canonicalize(), unless overridden in the derived class.

Returns:

the biproduct of canonicalization, or nullptr if no biproduct generated

template<typename Visitor>
inline bool visit(Visitor &&visitor, const bool atoms_only = false)

recursively visit this expression, i.e. call visitor on each subexpression in depth-first fashion.

See also

expr_range

Warning

this will only work for tree expressions; no checking is performed that each subexpression has only been visited once TODO make work for graphs

Template Parameters:

Visitor – a callable of type void(ExprPtr&) or void(const ExprPtr&)

Parameters:
  • visitor – the visitor object

  • atoms_only – if true, will visit only the leaves; the default is to visit all nodes

Returns:

true if this object was visited

template<typename Visitor>
inline bool visit(Visitor &&visitor, const bool atoms_only = false) const

const version of visit

inline auto begin_subexpr()
inline auto end_subexpr()
inline auto begin_subexpr() const
inline auto end_subexpr() const
inline Expr &expr()
inline const Expr &expr() const
inline virtual bool is_cnumber() const

Reports if this is a c-number (https://en.wikipedia.org/wiki/C-number), i.e. it commutes multiplicatively with c-numbers and q-numbers.

Note

for leaves this has O(1) cost, for non-leaves this involves checking subexpressions

Warning

this returns true for all leaves, hence must be overridden for leaf q-numbers

Returns:

true if this is a c-number

inline bool commutes_with(const Expr &that) const

Checks if this commutes (wrt multiplication) with that.

Note

the default implementation checks if either is c-number; if both are q-numbers this checks commutativity of each subexpression with (each subexpression of) that

Note

expressions are assumed to always commute with respect to additions since it does not appear that +nonabelian near-rings (https://en.wikipedia.org/wiki/Near-ring) are commonly needed.

Note

commutativity of leaves is checked by commutes_with_atom()

Returns:

true if this commutes with that

virtual void adjoint()

changes this to its adjoint

Note

base implementation throws, must be reimplemented in the derived class

inline hash_type hash_value(std::function<hash_type(const std::shared_ptr<const Expr>&)> hasher = {}) const

Computes and returns the hash value. If default hasher is used then the value will be memoized, otherwise hasher will be used to compute the hash every time.

Note

always returns 0 unless this derived class overrides Expr::memoizing_hash

Parameters:

hasher – the hasher object, if omitted, the default is used (

Returns:

the hash value for this Expr

virtual type_id_type type_id() const = 0

Computes and returns the derived type identifier

Note

this function must be overridden in the derived class

Returns:

the hash value for this Expr

template<typename T, typename = std::enable_if<is_an_expr_v<T>>>
inline bool operator<(const T &that) const

Note

the derived class must implement Expr::static_less_than

Template Parameters:

TExpr or a class derived from Expr

Returns:

true if *this is less than that

template<typename T>
inline bool is() const
Template Parameters:

T – an Expr type

Returns:

true if this object is of type T

template<typename T>
inline const T &as() const
Template Parameters:

T – an Expr type

Returns:

this object cast to type T

template<typename T>
inline T &as()
Template Parameters:

T – an Expr type

Returns:

this object cast to type T

inline std::string type_name() const

Note

uses RTTI

Returns:

the (demangled) name of this type

Public Static Functions

template<typename T>
static inline type_id_type get_type_id()
Returns:

(unique) type id of class T

template<typename T>
static inline void set_type_id(type_id_type id)

sets (unique) type id of class T

Note

since get_type_id does not check for duplicates, it’s user’s responsiblity to make sure that there are no collisions between type ids

Parameters:

id – the value of type id of class T

Protected Functions

Expr(Expr&&) = default
Expr(const Expr&) = default
Expr &operator=(Expr&&) = default
Expr &operator=(const Expr&) = default
inline virtual cursor begin_cursor()
Returns:

the cursor for the beginning of the range (must override in a derived Expr that has subexpressions)

inline virtual cursor end_cursor()
Returns:

the cursor for the end of the range (must override in a derived Expr that has subexpressions)

inline virtual cursor begin_cursor() const
Returns:

the cursor for the beginning of the range (must override in a derived Expr that has subexpressions)

inline virtual cursor end_cursor() const
Returns:

the cursor for the end of the range (must override in a derived Expr that has subexpressions)

inline virtual hash_type memoizing_hash() const
inline virtual void reset_hash_value() const
virtual bool static_equal(const Expr &that) const = 0

Note

that is guaranteed to be of same type as *this, hence can be statically cast

Parameters:

that – an Expr object

Returns:

true if that is equivalent to *this

inline virtual bool static_less_than(const Expr &that) const

Note

that is guaranteed to be of same type as *this, hence can be statically cast

Note

base comparison compares Expr::hash_value() , specialize to each type as needed

Parameters:

that – an Expr object

Returns:

true if *this is less than that

inline virtual bool commutes_with_atom(const Expr &that) const

Note

*this and that are guaranteed to be leaves, and neither is a c-number , hence honest checking is needed

Note

this returns true unless overridden in derived class

Parameters:

that – an Expr object

Returns:

true if *this multiplicatively commutes with that

Protected Attributes

mutable std::optional<hash_type> hash_value_

Friends

inline friend bool operator==(const Expr &a, const Expr &b)
Returns:

true if a is equal to b

struct cursor

Public Types

using value_type = ExprPtr

Public Functions

cursor() = default
inline explicit constexpr cursor(ExprPtr *subexpr_ptr) noexcept
inline explicit constexpr cursor(const ExprPtr *subexpr_ptr) noexcept

when take const ptr note runtime const flag

inline bool equal(const cursor &that) const
inline void next()
inline void prev()
inline ExprPtr &read() const
inline ExprPtr &read()
inline void assign(const ExprPtr &that_ptr)
inline std::ptrdiff_t distance_to(cursor const &that) const
inline void advance(std::ptrdiff_t n)
template<typename T, typename Enabler = void>
struct is_shared_ptr_of_expr : public std::false_type
template<>
struct is_shared_ptr_of_expr<ExprPtr, void> : public std::true_type
template<typename T> enable_if_t< is_expr_v< T > > > : public std::true_type
template<typename T, typename Enabler = void>
struct is_shared_ptr_of_expr_or_derived : public std::false_type
template<>
struct is_shared_ptr_of_expr_or_derived<ExprPtr, void> : public std::true_type
template<typename T> enable_if_t< is_an_expr_v< T > > > : public std::true_type