diff --git a/libcorpus2/tagset.cpp b/libcorpus2/tagset.cpp
index 77b2260494214d2cc354818e3c56cb791bca3b7e..b8957b9c4435d3419f299def1870b02f6a46521b 100644
--- a/libcorpus2/tagset.cpp
+++ b/libcorpus2/tagset.cpp
@@ -420,6 +420,11 @@ const std::string& Tagset::get_pos_name(idx_t pos) const
 	return pos_dict_.get_string(pos);
 }
 
+const std::string& Tagset::get_pos_name(mask_t pos) const
+{
+	return pos_dict_.get_string(get_pos_index(pos));
+}
+
 mask_t Tagset::get_pos_mask(const string_range& pos) const
 {
 	return get_pos_mask(get_pos_index(pos));
@@ -434,6 +439,15 @@ mask_t Tagset::get_pos_mask(idx_t pos) const
 	}
 }
 
+idx_t Tagset::get_pos_index(mask_t pos) const
+{
+	if (pos.none()) {
+		return -1;
+	} else {
+		return PwrNlp::lowest_bit(pos);
+	}
+}
+
 idx_t Tagset::get_attribute_index(const string_range& a) const
 {
 	return attribute_dict_.get_id(a);
diff --git a/libcorpus2/tagset.h b/libcorpus2/tagset.h
index b2d4dcf58363ac90b2738bfc6f460074d04f3651..35768f0a10ad3074d24cd0a0ed616878d38e5f78 100644
--- a/libcorpus2/tagset.h
+++ b/libcorpus2/tagset.h
@@ -266,7 +266,6 @@ public:
 		return attribute_dict_;
 	}
 
-
 	/// POS name -> index mapping
 	/// @returns -1 on invalid name
 	idx_t get_pos_index(const string_range& pos) const;
@@ -275,6 +274,10 @@ public:
 	/// @returns empty string on invalid index
 	const std::string& get_pos_name(idx_t pos) const;
 
+	/// POS mask -> name
+	/// @returns empty string on invalid index
+	const std::string& get_pos_name(mask_t pos) const;
+
 	/// POS name -> mask mapping
 	/// @return null mask on invalid name
 	mask_t get_pos_mask(const string_range& pos) const;
@@ -283,6 +286,10 @@ public:
 	/// @return null mask on invalid index
 	mask_t get_pos_mask(idx_t pos) const;
 
+	/// POS mask -> index mapping
+	/// @return -1 on empty mask, unspecified in more tha one POS set
+	idx_t get_pos_index(mask_t pos) const;
+
 
 	/// Attribute name -> index mapping
 	/// @returns -1 on invalid name