namespace ngraph::pattern

namespace pattern {

// namespaces

namespace ngraph::pattern::op;

// typedefs

typedef std::map<std::shared_ptr<Node>, OutputVector> RPatternValueMap;
typedef std::map<std::shared_ptr<Node>, Output<Node>> PatternValueMap;
typedef std::vector<PatternValueMap> PatternValueMaps;
typedef std::map<std::shared_ptr<Node>, std::shared_ptr<Node>> PatternMap;

// classes

class Matcher;
class MatcherState;
class RecurrentMatcher;

// global functions

NGRAPH_API std::shared_ptr<Node> any_input();
NGRAPH_API std::shared_ptr<Node> any_input(const pattern::op::ValuePredicate& pred);
PatternMap as_pattern_map(const PatternValueMap& pattern_value_map);
PatternValueMap as_pattern_value_map(const PatternMap& pattern_map);

template <typename T>
std::function<bool(std::shared_ptr<Node>)> has_class();

NGRAPH_API std::function<bool(Output<Node>)> consumers_count(size_t n);
NGRAPH_API std::function<bool(Output<Node>)> has_static_dim(size_t pos);
NGRAPH_API std::function<bool(Output<Node>)> has_static_dims(const std::vector<size_t>& dims);
NGRAPH_API std::function<bool(Output<Node>)> has_static_shape();
NGRAPH_API std::function<bool(Output<Node>)> has_static_rank();
NGRAPH_API std::function<bool(Output<Node>)> rank_equals(const Dimension& expected_rank);
NGRAPH_API std::function<bool(Output<Node>)> type_matches(const element::Type& type);
NGRAPH_API std::function<bool(Output<Node>)> type_matches_any(const std::vector<element::Type>& types);

template <class... Args>
std::shared_ptr<Node> wrap_type(
    const OutputVector& inputs,
    const pattern::op::ValuePredicate& pred
    );

template <class... Args>
std::shared_ptr<Node> wrap_type(const OutputVector& inputs = {});

template <class... Args>
std::shared_ptr<Node> wrap_type(const pattern::op::ValuePredicate& pred);

} // namespace pattern