namespace ov::pass::pattern

namespace pattern {

// namespaces

namespace ov::pass::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

OPENVINO_API std::shared_ptr<Node> any_input();
OPENVINO_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();

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

template <
    class T,
    typename std::enable_if<ngraph::HasTypeInfoMember<T>::value, bool>::type = true
    >
void collect_wrap_info(std::vector<DiscreteTypeInfo>& info);

template <
    class T,
    class... Targs,
    typename std::enable_if<sizeof...(Targs) !=0, bool>::type = true
    >
void collect_wrap_info(std::vector<DiscreteTypeInfo>& info);

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