@classmethod
def similarity(cls, node, target, include_substituents=True,
    include_modifications=True, include_children=False, exact=True,
    ignore_reduction=False, ignore_ring=False, treat_null_as_wild=True,
    match_attachement_positions=False, short_circuit_after=None, visited=None):
    """A heuristic comparison for measuring similarity between monosaccharides.

        Compares:
            1. ring_start and ring_end
            2. superclass
            3. configuration
            4. stem
            5. anomer
            6. If `include_modifications`, each modification
            7. If `include_substituents`, each substituent
            8. If `include_children`, each child |Monosaccharide|

        The result is two numbers, the observed similarity between `node` and `target`,
        and the similarity between `target` and itself. `expected - observed` is there
        number of differences observed between the two monosaccharides, which can be useful
        for expressing how far apart two monosaccharides are in feature space. For more distant
        similarity testing, especially when considering children, the ratio `observed / expected`
        might be used instead.

        Similarity is not symmetric, e.g. ``a -> b != b -> a``. A commutative version of similarity
        can be used by calculating both directions, and taking the result with the smallest error.

        Parameters
        ----------
        node : :class:`~.Monosaccharide`
            The reference monosaccharide
        target : :class:`~.Monosaccharide`
            The monosaccharide to compare against
        include_substituents: bool
            Include substituents in comparison (Defaults |True|)
        include_modifications: bool
            Include modifications in comparison (Defaults |True|)
        include_children: bool
            Include children in comparison (Defaults |False|)
        exact: bool
            Penalize for having unmatched attachments (Defaults |True|)
        ignore_reduction: bool
            Whether or not to include differences in reduction state as a
            mismatch
        ignore_ring: bool
            Whether or not to include differences in ring coordinates as
            a mismatch
        treat_null_as_wild: bool
            Whether or not to treat traits with a value of :const:`None` or
            :const:`~.UnknownPosition` as always matching when the null
            value is on the *target* residue (the residue that traits are being
            matched to).
        short_circuit_after: None or Number
            Controls whether to quit comparing nodes if the difference
            becomes too large, useful for speeding up pessimistic
            comparisons
        visited: set
            Tracks which node pairs have already been compared to break
            cycles. This carries state across multiple calls to :meth:`compare`
            and must be reset by calling :meth:`reset` before reusing an
            instance on new structures.

        Returns
        -------
        :class:`int`: observed
            The number of observed features that matched
        :class:`int`: expected
            The number of features that could have been matched
        """
    inst = cls(include_substituents=include_substituents,
        include_modifications=include_modifications, include_children=
        include_children, exact=exact, ignore_reduction=ignore_reduction,
        ignore_ring=ignore_ring, treat_null_as_wild=treat_null_as_wild,
        match_attachement_positions=match_attachement_positions,
        short_circuit_after=short_circuit_after, visited=visited)
    return inst.compare(node, target)
