#ifndef EMPATHY_SEMA_UNI_CONTEXT_H #define EMPATHY_SEMA_UNI_CONTEXT_H namespace empathy::sema { class UnificationRuleSet; class UnificationContext { public: static constexpr uint32_t InvalidIndex = numeric_limits< uint32_t >::max(); UnificationContext( const ptr< UnificationRuleSet >& rules ); UnificationContext( ptr< UnificationRuleSet >&& rules ); const auto& rules() const { return m_rules; } uint32_t getLHSHoleIndex( const StringId& name ) const; uint32_t getRHSHoleIndex( const StringId& name ) const; uint32_t createValue(); void setLHSHoleIndex( const StringId& name, uint32_t index ); void setRHSHoleIndex( const StringId& name, uint32_t index ); const optional< Term >& getValue( uint32_t index ) const { assert( m_values.size() > index ); return m_values[index].first; } template< typename T > void setValue( uint32_t index, T&& val, uint32_t complexity ) { assert( m_values.size() > index ); if( !m_values[index].first ) --m_numUnknownValues; m_complexity -= m_values[index].second; m_values = m_values.set( index, { forward< T >( val ), complexity } ); } UnificationContext& flip() { swap( m_currentLHSNamespaceIndex, m_currentRHSNamespaceIndex ); return *this; } void incComplexity( uint32_t n = 1 ) { m_complexity += n; } uint32_t numUnknownValues() const { return m_numUnknownValues; } uint32_t complexity() const { return m_complexity; } auto score() const { return UnificationScore( m_complexity, m_pCow->holeDict.size() ); } // Used to detect and reject recursive hole nesting. bool isHoleLocked( uint32_t index ) const; void lockHole( uint32_t index ); void unlockHole( uint32_t index ); private: ptr< UnificationRuleSet > m_rules; using StoredValue = pair< optional< Term >, uint32_t >; immer::vector< StoredValue > m_values; uint32_t m_currentLHSNamespaceIndex = 1; uint32_t m_currentRHSNamespaceIndex = 2; uint32_t m_numUnknownValues = 0; uint32_t m_complexity = 0; using HoleName = pair< StringId, uint32_t >; struct Cow { unordered_map< HoleName, uint32_t > holeDict; unordered_set< uint32_t > lockedHoles; }; ptr< Cow > m_pCow = make_shared< Cow >(); }; } #endif