#include <iostream>
#include <utility>
#include <vector>
#include <sstream>

using namespace std;

class Relation
{
public:
    Relation(): relations{} {}

    void add_relation(pair<char, char> relation)
    {
	relations.push_back(relation);
    }

    string to_string() const
    {
	stringstream strstream{};
	for (pair<char, char> relation : relations)
	{
	    strstream << relation.first << "->" << relation.second << " ";
	}
	return strstream.str();
    }

    Relation compose(Relation const& other) const
    {
	Relation result{};
	for( pair<char, char> relation : relations )
	{
	    for( pair<char, char> other_relation: other.relations )
	    {
		if (relation.second == other_relation.first)
		{
		    result.add_relation(pair<char, char>{relation.first, other_relation.second});
		}
	    }
	}
	return result;
    }
    
private:
    vector<pair<char, char>> relations;
};

int main()
{
    Relation r1{};
    r1.add_relation(pair<char, char> {'a', 'b'});
    r1.add_relation(pair<char, char> {'b', 'a'});
    cout << "r1: " << r1.to_string() << endl;

    Relation r2{};
    r2.add_relation(pair<char, char> {'a', 'b'});
    r2.add_relation(pair<char, char> {'b', 'c'});
    r2.add_relation(pair<char, char> {'c', 'd'});
    r2.add_relation(pair<char, char> {'d', 'a'});
    cout << "r2: " << r2.to_string() << endl;

    Relation r3{r1.compose(r2)};
    cout << "r3: " << r3.to_string() << endl;
}

// R1 â—¦ R2 = R3
// R1 ◦ R2 := {(a, c) ∈ A × C | ∃b ∈ B (R1(a, b) ∧ R2(b, c))}