Goose  Artifact [6c96ac9913]

Artifact 6c96ac991303aace1d13a13af060b107e350459832774a95cf4e85e3a2998122:

  • File bs/sema/unify.h — part of check-in [f764dd2384] at 2018-12-17 14:39:33 on branch trunk — Refactored unify as a generator that can yield multiple solutions, along with a score to order them. (user: achavasse size: 2666)

#ifndef EMPATHY_SEMA_UNIFY_H
#define EMPATHY_SEMA_UNIFY_H

namespace empathy::sema
{
    class UnificationScore
    {
        public:
            UnificationScore() {}

            UnificationScore( uint32_t complexity, uint32_t uniqueHoles ) :
                m_complexity( complexity ),
                m_uniqueHoles( uniqueHoles )
            {}

            auto& operator+=( const UnificationScore& rhs )
            {
                m_complexity += rhs.m_complexity;
                m_uniqueHoles += rhs.m_uniqueHoles;
                return *this;
            }

            auto operator+( const UnificationScore& rhs ) const
            {
                return UnificationScore( m_complexity + rhs.m_complexity, m_uniqueHoles + rhs.m_uniqueHoles );
            }

            bool operator==( const UnificationScore& rhs ) const
            {
                return m_complexity == rhs.m_complexity
                    && m_uniqueHoles == rhs.m_uniqueHoles;
            }

            bool operator!=( const UnificationScore& rhs ) const
            {
                return !operator==( rhs );
            }

            bool operator<( const UnificationScore& rhs ) const
            {
                if( m_complexity != rhs.m_complexity )
                    return m_complexity < rhs.m_complexity ;

                return m_uniqueHoles > rhs.m_uniqueHoles;
            }

            bool operator>( const UnificationScore& rhs ) const
            {
                if( m_complexity != rhs.m_complexity )
                    return m_complexity > rhs.m_complexity ;

                return m_uniqueHoles < rhs.m_uniqueHoles;
            }

            bool operator<=( const UnificationScore& rhs ) const
            {
                return !operator>( rhs );
            }

            bool operator>=( const UnificationScore& rhs ) const
            {
                return !operator<( rhs );
            }

        private:
            uint32_t m_complexity = 0;
            uint32_t m_uniqueHoles = 0;
    };

    class Unification
    {
        public:
            template< typename T >
            Unification( T&& expr, const UnificationScore& score ) :
                m_expr( forward< T >( expr ) ),
                m_score( score )
            {}

            const auto& expr() const { return m_expr; }
            const auto& score() const { return m_score; }
            auto& score() { return m_score; }

        private:
            Term m_expr;
            UnificationScore m_score;
    };

    using UniGen = Generator< Unification >;

    UniGen Unify( const Term& lhs, const Term& rhs, UnificationContext& context );
}

#endif