#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