#!/usr/bin/perl

#
# sos_as_string($set) returns a stringified representation of
# a set of sets.  $string is initially undefined, and is filled
# in only when sos_as_string() calls itself later.
#
sub sos_as_string ($;$) {
    my ( $set, $string ) = @_;

    $$string .= '{';                             # The beginning brace

    my $i;                                       # Number of members

    foreach my $key ( keys %{ $set } ) {
        # Add space between the members.
        $$string .= ' ' if $i++;
        if ( ref $set->{ $key } ) {
            sos_as_string( $set->{ $key }, $string );  # Recurse
        } else {
            $$string .= $key;                          # Add a member
        }
    }

    return $$string .= '}';                      # The ending brace
}

my $a  = { ab => 12, cd => 34, ef => 56 };
# Remember that sets of sets are represented by the key and
# the value being equal: hence the $a, $a and $b, $b and $n1, $n1.
my $b  = { pq => 23, rs => 45, tu => 67, $a, $a };
my $c  = { xy => 78, $b, $b, zx => 89 };

my $n1 = { };
my $n2 = { $n1, $n1 };

print "a  = ", sos_as_string( $a  ), "\n";
print "b  = ", sos_as_string( $b  ), "\n";
print "c  = ", sos_as_string( $c  ), "\n";
print "n1 = ", sos_as_string( $n1 ), "\n";
print "n2 = ", sos_as_string( $n2 ), "\n";
