public IEnumerable <(string Word, WordNet.PointerSymbol Symbol, PartOfSpeech PartOfSpeech, byte Source, byte Target)> GetPointers(string word, int lexId = -1)
            {
                ulong uniqueId = 0;

                while (true)
                {
                    if (lexId < 0)
                    {
                        ulong lexID    = 0;
                        bool  foundAny = false;
                        while (true)
                        {
                            var wordHash = WordNet.HashWordIgnoreCaseUnderscoreIsSpace(word, lexID, uniqueId);

                            if (HashToOffset.TryGetValue(wordHash, out var offset))
                            {
                                foundAny = true;
                                var term = Terms[offset];

                                var pointers = Pointers.AsSpan().Slice(term.PointersStart, term.PointersLength).ToArray();

                                for (int i = 0; i < pointers.Length; i++)
                                {
                                    var         p = pointers[i];
                                    WordNetData otherData;
                                    switch (p.PartOfSpeech)
                                    {
                                    case PartOfSpeech.NOUN: otherData = WordNet.Nouns; break;

                                    case PartOfSpeech.VERB: otherData = WordNet.Verbs; break;

                                    case PartOfSpeech.ADJ: otherData = WordNet.Adjectives; break;

                                    case PartOfSpeech.ADV: otherData = WordNet.Adverbs; break;

                                    default: continue;
                                    }
                                    var otherTerm = otherData.Terms[p.Offset];
                                    yield return(otherData.GetWordFromCache(otherTerm.WordStart, otherTerm.WordLength), p.Symbol, p.PartOfSpeech, p.Source, p.Target);
                                }

                                lexID++;
                            }
                            else
                            {
                                break;
                            }
                        }
                        if (!foundAny)
                        {
                            break;
                        }
                    }
                    else
                    {
                        var wordHash = WordNet.HashWordIgnoreCaseUnderscoreIsSpace(word, (ulong)lexId, uniqueId);

                        if (HashToOffset.TryGetValue(wordHash, out var offset))
                        {
                            var term = Terms[offset];

                            var pointers = Pointers.AsSpan().Slice(term.PointersStart, term.PointersLength).ToArray();
                            for (int i = 0; i < pointers.Length; i++)
                            {
                                var         p = pointers[i];
                                WordNetData otherData;
                                switch (p.PartOfSpeech)
                                {
                                case PartOfSpeech.NOUN: otherData = WordNet.Nouns; break;

                                case PartOfSpeech.VERB: otherData = WordNet.Verbs; break;

                                case PartOfSpeech.ADJ: otherData = WordNet.Adjectives; break;

                                case PartOfSpeech.ADV: otherData = WordNet.Adverbs; break;

                                default: continue;
                                }
                                var otherTerm = otherData.Terms[p.Offset];
                                yield return(otherData.GetWordFromCache(otherTerm.WordStart, otherTerm.WordLength), p.Symbol, p.PartOfSpeech, p.Source, p.Target);
                            }
                        }
                        else
                        {
                            break;
                        }
                    }

                    uniqueId++;
                }
            }
            public IEnumerable <(string Word, int LexId)> GetSynonyms(string word, int lexId = -1)
            {
                ulong uniqueId = 0;

                while (true)
                {
                    if (lexId < 0)
                    {
                        ulong lexID    = 0;
                        bool  foundAny = false;
                        while (true)
                        {
                            var wordHash = WordNet.HashWordIgnoreCaseUnderscoreIsSpace(word, lexID, uniqueId);

                            if (HashToOffset.TryGetValue(wordHash, out var offset))
                            {
                                foundAny = true;
                                var term = Terms[offset];
                                yield return(GetWordFromCache(term.WordStart, term.WordLength), term.LexID);

                                if (term.WordsLength > 0)
                                {
                                    var others = OtherWordsCache.AsSpan(term.WordsStart, term.WordsLength).ToArray();
                                    for (int i = 0; i < others.Length; i += 3)
                                    {
                                        yield return(GetWordFromCache(others[i], others[i + 1]), others[i + 2]);
                                    }
                                }

                                lexID++;
                            }
                            else
                            {
                                break;
                            }
                        }
                        if (!foundAny)
                        {
                            break;
                        }
                    }
                    else
                    {
                        var wordHash = WordNet.HashWordIgnoreCaseUnderscoreIsSpace(word, (ulong)lexId, uniqueId);

                        if (HashToOffset.TryGetValue(wordHash, out var offset))
                        {
                            var term = Terms[offset];
                            yield return(GetWordFromCache(term.WordStart, term.WordLength), term.LexID);

                            if (term.WordsLength > 0)
                            {
                                var others = OtherWordsCache.AsSpan(term.WordsStart, term.WordsLength).ToArray();
                                for (int i = 0; i < others.Length; i += 3)
                                {
                                    yield return(GetWordFromCache(others[i], others[i + 1]), others[i + 2]);
                                }
                            }
                        }
                        else
                        {
                            break;
                        }
                    }

                    uniqueId++;
                }
            }