示例#1
0
        public ComplexChain RandomEChain()
        {
            Dictionary <int, int> odds = new Dictionary <int, int>
            {
                { 1, 74 },
                { 2, 10 },
                { 3, 10 },
                { 4, 5 },
                { 5, 1 },
            };

            ConvertToCummulative(odds);

            int dice    = random.Next(0, 101);
            var howMany = odds.Where(x => dice <= x.Value).Select(x => x.Key).First();

            List <ComplexChain> directObjects = new List <ComplexChain>();

            while (howMany > 0)
            {
                directObjects.Add(RandomEnPiChain());
                howMany--;
            }

            ComplexChain c = new ComplexChain(Particles.e, directObjects.ToArray());

            return(c);
        }
示例#2
0
        private void ProcessHeadVocatives(string[] vocativeParts, List <Vocative> headVocatives, bool allAreVocatives)
        {
            bool vocativesDone = false;

            //Process head vocatives.
            for (int i = 0; i < vocativeParts.Length; i++)
            {
                if (!allAreVocatives)
                {
                    if (i == vocativeParts.Length - 1)
                    {
                        continue;
                    }
                }

                string vocativePart = vocativeParts[i];
                if (vocativesDone)
                {
                    continue;
                }

                if (vocativePart.ContainsCheck(" li ", " e "))
                {
                    vocativesDone = true;
                }

                ComplexChain vocativeChain = ProcessEnPiChain(vocativePart);
                Vocative     v             = new Vocative(vocativeChain);
                headVocatives.Add(v);
            }
        }
示例#3
0
        private TpPredicate GeneratePredicate()
        {
            bool isTransitive = random.Next(0, 100) < 50;

            VerbPhrase   verbPhrase = RandomVerbPhrase(isTransitive ? "vt" : "vi");
            ComplexChain nominal    = RandomEnPiChain();

            TpPredicate p;

            if (random.Next(0, 100) < 75)
            {
                PrepositionalPhrase[] prepositionals = null;
                if (random.Next(0, 100) < 35)
                {
                    prepositionals = RandomPrepChain();
                }

                ComplexChain directs = null;
                if (isTransitive)
                {
                    directs = RandomEChain();
                }

                p = new TpPredicate(Particles.li, verbPhrase, directs, prepositionals);
            }
            else
            {
                p = new TpPredicate(Particles.li, nominal);
            }
            return(p);
        }
示例#4
0
        private static Sentence EstablishAFact(KeyValuePair <string, string> pair)
        {
            string[] nameParts = pair.Key.Split(new[] { " " }, StringSplitOptions.RemoveEmptyEntries);

            Word jan  = Words.jan;
            Word name = new Word(nameParts[1]);

            Word nanpa   = Words.nanpa;
            Word fiveEtc = new Word(pair.Value);

            ComplexChain subject = ComplexChain.SinglePiEnChainFactory(new HeadedPhrase(jan, new WordSet {
                name
            }));
            VerbPhrase   verb    = new VerbPhrase(Words.jo);
            ComplexChain directs = ComplexChain.SingleEPiChainFactory(new HeadedPhrase(nanpa, new WordSet {
                fiveEtc
            }));

            TpPredicate predicate = new TpPredicate(Particles.li, verb, directs);
            Sentence    fact      = new Sentence(subject, new PredicateList {
                predicate
            }, SentenceDiagnostics.NotFromParser,
                                                 new SentenceOptionalParts
            {
                Punctuation = new Punctuation(".")
            });

            return(fact);
        }
示例#5
0
        //This only works for 1 subject!
        //kule pi walo en pimeja
        public ComplexChain ProcessBackwardsPiEnChain(string subjects)
        {
            if (String.IsNullOrEmpty(subjects))
            {
                throw new ArgumentException("Cannot parse null/empty subjects");
            }
            foreach (var particle in new[] { "la", "li" })
            {
                if (subjects.StartsOrContainsOrEnds(particle))
                {
                    throw new ArgumentException("Subject phrase : " + subjects + " Contains " + particle + ". This is not possible.");
                }
            }

            string[] singleSubjectWithCompoundModifers = Splitters.SplitOnPi(subjects);

            //Split on pi
            //jan pi pali suli en soweli pi tawa wawa

            //jan ~tan ma pi pali suli ~tawa mani pi ma suli en soweli pi tawa wawa
            //jan ~tan ma pi pali suli ~tawa mani pi ma suli /en/ soweli pi tawa wawa
            //jan ~tan ma //pi// pali suli ~tawa mani //pi// ma suli /en/ soweli //pi// tawa wawa

            //BUG: Following code wraps simple chain in unnecessary complex chain.
            List <ComplexChain> subChains = new List <ComplexChain>();

            for (int i = 0; i < singleSubjectWithCompoundModifers.Length; i++)
            {
                string piChains = singleSubjectWithCompoundModifers[i];

                if (piChains == "")
                {
                    continue; //But how did that happen?
                }
                string[] enLessTokens = Splitters.SplitOnEn(piChains);

                List <Chain> piCollection = new List <Chain>();
                foreach (string enLessToken in enLessTokens)
                {
                    Chain piPhrase = ProcessPiChain(enLessToken);
                    piCollection.Add(piPhrase);
                }
                ComplexChain piChain = new ComplexChain(Particles.en, piCollection.ToArray());
                subChains.Add(piChain);
            }

            //if (subChains[0].SubChains.Length > 1 && subChains[0].SubChains.Last().ToString().Split(new char[] { '*', ' ', '-' }).Length == 1)
            //{
            //    throw new TpSyntaxException("final pi in pi chain must be followed by 2 words, otherwise just use juxtaposition (i.e. 2 adjacent words with no particle) : " + subjects);
            //}

            ComplexChain subject = new ComplexChain(Particles.pi, subChains.ToArray());

            return(subject);
        }
示例#6
0
        private static void ProcessSubjects(bool includePos, Sentence s, List <string> gloss, Dialect dialect)
        {
            ComplexChain c = s.Subjects;

            if (c == null)
            {
                //Imperatives have implicit subjects.
                return;
            }
            ProcessOneChain(includePos, gloss, dialect, c);
        }
        public void ProcessSingletonEnChainNoEn()
        {
            Dialect     c  = Dialect.LooseyGoosey;
            ParserUtils pu = new ParserUtils(c);

            ComplexChain list = pu.ProcessEnPiChain("jan Mato");

            Console.WriteLine(list);
            //Assert.AreEqual(1, list.SubChains[0].SubChains.Length);
            //Assert.AreEqual("jan", list.SubChains[0].SubChains[0].HeadedPhrases.Head.Text);
            //Assert.AreEqual("Mato", list.SubChains[0].HeadedPhrases[0].Modifiers.First().Text);
        }
示例#8
0
        public ComplexChain RandomEnPiChain()
        {
            Word    headWord  = RandomWord("noun");
            WordSet modifiers = new WordSet {
                RandomWord("adj")
            };
            List <Chain> agents = new List <Chain>();

            agents.Add(new Chain(Particles.pi, new[] { new HeadedPhrase(headWord, modifiers) }));
            ComplexChain c = new ComplexChain(Particles.en, agents.ToArray());

            return(c);
        }
        public void ProcessSingletonEnChainOneEn()
        {
            Dialect     c  = Dialect.LooseyGoosey;
            ParserUtils pu = new ParserUtils(c);

            ComplexChain list = pu.ProcessEnPiChain("jan en soweli");

            Console.WriteLine(list.ToJsonNet());
            Console.WriteLine(list);
            //Assert.AreEqual(1, list.SubChains[0].HeadedPhrases.Length);
            //Assert.AreEqual(list.SubChains[0].HeadedPhrases[0].Head.Text, "jan");
            //Assert.AreEqual(list.SubChains[1].HeadedPhrases[0].Head.Text, "soweli");
        }
示例#10
0
        //Simple Sentences
        public Sentence(ComplexChain subjects, PredicateList predicates, SentenceDiagnostics diagnostics, SentenceOptionalParts parts = null)
        {
            LaFragment      = new List <Fragment>();
            this.subjects   = subjects;   //only (*), o, en
            this.predicates = predicates; //only li, pi, en
            if (parts != null)
            {
                punctuation    = parts.Punctuation;
                tagConjunction = parts.Conjunction;
                tagQuestion    = parts.TagQuestion;
                headVocatives  = parts.HeadVocatives;
                isHortative    = parts.IsHortative;
            }

            this.diagnostics = diagnostics;
        }
示例#11
0
        public ComplexChain RandomEnPiChainOfProperModifers()
        {
            Word headWord;
            int  dice = random.Next(0, 100);

            if (dice < 70)
            {
                headWord = Words.jan;
            }
            else if (dice < 84)
            {
                headWord = Words.meli;
            }
            else if (dice < 99)
            {
                headWord = Words.mije;
            }
            else
            {
                headWord = Words.soweli;
            }

            WordSet modifiers;

            if (random.Next(0, 100) < 75)
            {
                modifiers = new WordSet {
                    Neologism.MakeProperNeologism()
                };
            }
            else
            {
                modifiers = new WordSet {
                    Neologism.MakeProperNeologism(), Neologism.MakeProperNeologism()
                };
            }

            List <Chain> agents = new List <Chain>();

            agents.Add(new Chain(Particles.pi, new[] { new HeadedPhrase(headWord, modifiers) }));
            ComplexChain c = new ComplexChain(Particles.en, agents.ToArray());

            return(c);
        }
示例#12
0
        private static Sentence CreateQuestion()
        {
            Word jan     = Words.seme;
            Word nanpa   = Words.nanpa;
            Word fiveEtc = new Word("555-1234");

            ComplexChain subject = ComplexChain.SinglePiEnChainFactory(new HeadedPhrase(jan));
            VerbPhrase   verbs   = new VerbPhrase(Words.jo);

            ComplexChain directs = ComplexChain.SingleEPiChainFactory(new HeadedPhrase(nanpa, new WordSet {
                fiveEtc
            }));
            TpPredicate predicate = new TpPredicate(Particles.li, verbs, directs);
            Sentence    fact      = new Sentence(subject, new PredicateList {
                predicate
            }, SentenceDiagnostics.NotFromParser);

            return(fact);
        }
示例#13
0
        public ComplexChain ProcessEnPiChain(string subjects)
        {
            if (String.IsNullOrEmpty(subjects))
            {
                throw new ArgumentException("Cannot parse null/empty subjects");
            }

            //if (processEnPiChainMemo.ContainsKey(value))
            //{
            //    return processEnPiChainMemo[value];
            //}

            foreach (var particle in new[] { "la", "li" })
            {
                if (subjects.StartsOrContainsOrEnds(particle))
                {
                    throw new ArgumentException("Subject phrase : " + subjects + " Contains " + particle + ". This is not possible.");
                }
            }

            string[] subjectTokens = Splitters.SplitOnEn(subjects);

            //Split on pi
            //jan pi pali suli en soweli pi tawa wawa

            //jan ~tan ma pi pali suli ~tawa mani pi ma suli en soweli pi tawa wawa
            //jan ~tan ma pi pali suli ~tawa mani pi ma suli /en/ soweli pi tawa wawa
            //jan ~tan ma //pi// pali suli ~tawa mani //pi// ma suli /en/ soweli //pi// tawa wawa

            //BUG: Following code wraps simple chain in unnecessary complex chain.
            List <ComplexChain> subChains = new List <ComplexChain>();

            for (int i = 0; i < subjectTokens.Length; i++)
            {
                string piChains = subjectTokens[i];

                if (piChains == "")
                {
                    continue; //But how did that happen?
                }
                string[] piLessTokens = Splitters.SplitOnPi(piChains);

                List <Chain> piCollection = new List <Chain>();
                foreach (string piLessToken in piLessTokens)
                {
                    Chain piPhrase = ProcessPiChain(piLessToken);
                    piCollection.Add(piPhrase);
                }
                ComplexChain piChain = new ComplexChain(Particles.pi, piCollection.ToArray());
                subChains.Add(piChain);
            }

            if (subChains[0].SubChains.Length > 1 && subChains[0].SubChains.Last().ToString().Split(new[] { '*', ' ', '-' }).Length == 1)
            {
                string lastWord = subChains[0].SubChains.Last().ToString();
                if (Number.IsPomanNumber(lastWord) && lastWord.Replace("#", "").Length > 1)
                {
                    //Poman numbers with 2 letters or more represent 2+ words.
                }
                else if (subjects.Contains(" en "))
                {
                    //HACK: maybe a compound modifier.  This actually usually fails.
                    return(ProcessBackwardsPiEnChain(subjects));
                }
                else
                {
                    throw new TpSyntaxException("final pi in pi chain must be followed by 2 words, otherwise just use juxtaposition (i.e. 2 adjacent words with no particle) : " + subjects);
                }
            }

            ComplexChain subjectChain = new ComplexChain(Particles.en, subChains.ToArray());

            //processEnPiChainMemo.Add(subjects,subjectChain);
            return(subjectChain);
        }
示例#14
0
        private static void ProcessOneChain(bool includePos, List <string> gloss, Dialect dialect, ComplexChain c, bool surpressFirstPreposition = false)
        {
            //Recurse
            if (c.ComplexChains != null)
            {
                int k = 0;
                foreach (var innerComplexChain in c.ComplexChains)
                {
                    k++;
                    if (k != 1)
                    {
                        gloss.Add(innerComplexChain.Particle.ToString(PartOfSpeech.Conjunction + ":" + includePos, dialect));
                    }
                    ProcessOneChain(includePos, gloss, dialect, innerComplexChain);
                }
            }

            //Almost to a leaf
            int i = 0;

            if (c.SubChains != null)
            {
                foreach (Chain sub in c.SubChains)
                {
                    i++;
                    if (i != 1)
                    {
                        gloss.Add(sub.Particle.ToString(PartOfSpeech.Conjunction + ":" + includePos, dialect));
                    }

                    foreach (HeadedPhrase hp in sub.HeadedPhrases)
                    {
                        ProcessingleHeadedPhrase(includePos, gloss, dialect, hp);
                    }
                }
            }
        }
示例#15
0
        public Sentence ProcessSimpleSentence(string sentence, Punctuation punctuation, string original)
        {
            //Think this is causing a bug.
            ////HACK: Still need a better way to deal with quotes.
            //if (sentence.EndCheck("»") || sentence.EndCheck("«"))
            //{
            //    sentence = sentence.Substring(0, sentence.Length - 1);
            //}



            //Comment? Get out of here!
            if (sentence.StartCheck("///"))
            {
                Comment c = new Comment(sentence);
                return(new Sentence(c, diagnostics));
            }

            //Simple exclamation! Get out of here!
            if (Exclamation.IsExclamation(sentence))
            {
                return(new Sentence(new Exclamation(new HeadedPhrase(new Word(sentence))), punctuation, new SentenceDiagnostics(original, sentence)));
            }

            List <Vocative> headVocatives = null;

            //jan Mato o, ale li pona. Head vocative!
            //kin la o moku. //not a vocative (hopefully dealt with elsewhere)
            //jan Mato o moku! //Head vocative, & imperative, with 2nd o discarded
            //jan Mato o o moku! //Head vocative, & imperative, with 2nd o discarded


            if (sentence.ContainsCheck(" o o "))//Explicit vocative & imperative
            {
                //Okay, we know exactly when the head vocatives end.
                headVocatives = new List <Vocative>();
                string justHeadVocatives = sentence.Substring(0, sentence.IndexOf(" o o ", StringComparison.Ordinal));

                //Process head vocatives.
                ProcessHeadVocatives(Splitters.SplitOnO(justHeadVocatives), headVocatives, allAreVocatives: true);
                //BUG: Add the dummy! (And it still doesn't work!)
                sentence = "jan Sanwan o " + sentence.Substring(sentence.IndexOf(" o o ", StringComparison.Ordinal) + 5);
            }


            //Starts with o, then we have imperative & no head vocatives.
            bool endsOrStartsWithO = sentence.StartCheck("o ") && sentence.EndCheck(" o");

            if (!endsOrStartsWithO)
            {
                //jan So o! (We already deal with degenerate vocative sentences elsewhere)
                //jan So o sina li nasa.
                //jan So o nasa!
                //jan So o mi mute o nasa.  <-- This is the problem.

                //These could be vocatives or imperatives.
                if (sentence.ContainsCheck(" o ", " o,", ",o ") && sentence.ContainsCheck(" li "))
                {
                    headVocatives = new List <Vocative>();

                    ProcessHeadVocatives(Splitters.SplitOnO(sentence), headVocatives, allAreVocatives: false);

                    //int firstLi = sentence.IndexOf(" li ");
                    int lastO = sentence.LastIndexOf(" o ", StringComparison.Ordinal);
                    if (lastO < 0)
                    {
                        lastO = sentence.LastIndexOf(" o,", StringComparison.Ordinal);
                    }

                    sentence = sentence.Substring(lastO + 2);
                }
            }

            //Process tag conjunctions and tag questions
            Particle    conjunction = null;
            TagQuestion tagQuestion = null;

            if (sentence.StartCheck("taso "))
            {
                conjunction = Particles.taso;
                sentence    = sentence.Substring(5);
            }
            else if (sentence.StartCheck("anu "))
            {
                conjunction = Particles.anu;
                sentence    = sentence.Substring(4);
            }
            else if (sentence.StartCheck("en "))
            {
                //Well, either parse it or throw. Otherwise, this gets skipped.
                //is this legal?
                conjunction = Particles.en;
                sentence    = sentence.Substring(3);
            }
            else if (sentence.StartCheck("ante ")) //never seen it.
            {
                conjunction = Particles.ante;
                sentence    = sentence.Substring(5);
            }

            //Should already have ? stripped off
            if (sentence.EndsWith(" anu seme"))
            {
                tagQuestion = new TagQuestion();
                sentence    = sentence.Substring(0, sentence.LastIndexOf(" anu seme", StringComparison.Ordinal));
            }


            if (sentence.EndCheck(" li"))
            {
                throw new TpParseException("Something went wrong-- sentenc ends with li. " + sentence);
            }
            if (sentence.StartsOrContainsOrEnds("la"))
            {
                throw new TpParseException("If it contains a la, anywhere, it isn't a simple sentence. " + sentence);
            }

            bool isHortative  = false;
            bool isImperative = false;

            if (sentence.StartCheck("o ") && sentence.ContainsCheck(" li "))
            {
                //o mi mute li moku
                isHortative = true;
                sentence    = sentence.RemoveLeadingWholeWord("o");
            }
            if (sentence.StartCheck("o ") && !sentence.ContainsCheck(" li "))
            {
                //o pana e pan
                isImperative = true;
                //sentence = sentence.RemoveLeadingWholeWord("o");
            }
            // someting o ==> vocative

            string[] liParts = Splitters.SplitOnLiOrO(sentence);

            if (liParts.Length == 1 && Exclamation.IsExclamation(liParts[0]))
            {
                //HACK: Duplicate code. & it only deals with a single final puncution mark.
                string possiblePunctuation = sentence[sentence.Length - 1].ToString();
                if (Punctuation.TryParse(possiblePunctuation, out punctuation))
                {
                    sentence = sentence.Substring(0, sentence.Length - 1);
                }

                //The whole thing is o! (or pakala! or the like)
                //pona a! a a a! ike a!
                TokenParserUtils tpu = new TokenParserUtils();

                Word[]       tokes         = tpu.ValidWords(sentence);
                HeadedPhrase parts         = new HeadedPhrase(tokes[0], new WordSet(ArrayExtensions.Tail(tokes)));
                bool         modifiersAreA = true;

                foreach (Word w in parts.Modifiers)
                {
                    if (w == "a")
                    {
                        continue;           //peculiar to exclamations & repeats.
                    }
                    if (w == "kin")
                    {
                        continue;             //modifies just about anything
                    }
                    modifiersAreA = false;
                }

                if (modifiersAreA)
                {
                    Exclamation exclamation = new Exclamation(parts);
                    Sentence    s           = new Sentence(exclamation, punctuation, diagnostics);
                    return(s);
                }
            }


            //Degenerate sentences.
            if (liParts[liParts.Length - 1].Trim(new char[] { ',', '«', '»', '!', ' ' }) == "o")
            {
                //We have a vocative sentence...
                Vocative vocative = new Vocative(ProcessEnPiChain(liParts[0]));
                Sentence s        = new Sentence(vocative, punctuation, diagnostics);
                return(s);
            }

            string subjects = liParts[0].Trim();

            ComplexChain subjectChain = null;
            int          startAt      = 1; //slot 0 is normally a subject

            if (subjects.Contains("«"))
            {
                int foo = 3;
            }
            if (subjects.StartCheck("o ") ||
                subjects.StartCheck("«o "))
            {
                //This is a verb phrase with implicit subjects!
                startAt = 0;
            }
            else
            {
                subjectChain = ProcessEnPiChain(subjects);
            }

            PredicateList verbPhrases = new PredicateList();

            for (int i = startAt; i < liParts.Length; i++)
            {
                string predicate = liParts[i].Trim();

                verbPhrases.Add(ProcessPredicates(predicate));
            }

            //Head or complete sentence.

            Sentence parsedSentence = new Sentence(subjectChain, verbPhrases, diagnostics, new SentenceOptionalParts
            {
                Conjunction = conjunction,
                //Etc
                Punctuation   = punctuation,
                IsHortative   = isHortative,
                TagQuestion   = tagQuestion,
                HeadVocatives = headVocatives != null ? headVocatives.ToArray() : null
            });

            return(parsedSentence);
        }
示例#16
0
 /// <summary>
 /// Initializes a new instance of the <see cref="Filter"/> class.
 /// </summary>
 /// <param name="chain">
 /// The chain.
 /// </param>
 public Filter(ComplexChain chain)
 {
     Chain = chain.Clone();
 }
 /// <summary>
 /// Returns the state of criterion. True, if everything is done, false - otherwise.
 /// </summary>
 /// <param name="chain">
 /// The chain.
 /// </param>
 /// <param name="alphabet">
 /// Chains alphabet.
 /// </param>
 /// <returns>
 /// The state of criterion.
 /// </returns>
 public abstract bool State(ComplexChain chain, FrequencyDictionary alphabet);
 /// <summary>
 /// Returns distortion between necessary and calculated value.
 /// For example between theoretical and practical values.
 /// </summary>
 /// <param name="chain">
 /// The chain.
 /// </param>
 /// <param name="alphabet">
 /// The alphabet.
 /// </param>
 /// <returns>
 /// The <see cref="double"/>.
 /// </returns>
 public abstract double Distortion(ComplexChain chain, FrequencyDictionary alphabet);
示例#19
0
        // jan li jo e soweli e kili e wawa lon anpa tawa anpa
        //     li jo e soweli e kili e wawa lon anpa tawa anpa
        public TpPredicate ProcessPredicates(string liPart)
        {
            if (String.IsNullOrWhiteSpace(liPart))
            {
                throw new TpParseException("Missing argument, cannot continue");
            }
            if (liPart == "li")
            {
                throw new TpParseException("Cannot do anything with just li");
            }
            TokenParserUtils pu = new TokenParserUtils();
            Particle         verbPhraseParticle;
            ComplexChain     directObjectChain = null;
            VerbPhrase       verbPhrase        = null;

            PrepositionalPhrase[] prepositionalChain = null;
            ComplexChain          nominalPredicate   = null;
            PiPredicate           piPredicate        = null;

            //Transitive Path.
            if (liPart.Split(new[] { ' ', '\t' }).Contains("e"))
            {
                string[] eParts = Splitters.SplitOnE(liPart);

                string[] verbPhraseParts = pu.WordsPunctuationAndCompounds(eParts[0]); //Could contain particles.

                if (!Token.CheckIsParticle(verbPhraseParts[0]))
                {
                    throw new TpSyntaxException("uh-oh not a particle: " + verbPhraseParts[0] + " from " + liPart);
                }
                verbPhraseParticle = new Particle(verbPhraseParts[0]);

                //Only process preps in normalized sentences
                string[] partsWithPreps = null;

                if (verbPhraseParts.Length > 1)
                {
                    if (verbPhraseParts.Any(x => x == "pi"))
                    {
                        //nominal predicate
                        nominalPredicate =
                            new ComplexChain(Particles.en,
                                             new[] {
                            ProcessPiChain(String.Join(" ", ArrayExtensions.Tail(verbPhraseParts)))
                        });
                    }
                    else
                    {
                        verbPhrase = VerbPhraseParser(ArrayExtensions.Tail(verbPhraseParts));
                    }
                }

                string verbsMaybePrepositions = eParts[eParts.Length - 1];


                if (verbsMaybePrepositions.ContainsCheck("~"))
                {
                    partsWithPreps = Splitters.SplitOnPrepositions(verbsMaybePrepositions);
                    if (partsWithPreps.Length == 1)
                    {
                        //This is the last e phrase or 1st prep.
                        if (partsWithPreps[0].ContainsCheck("~"))
                        {
                            //That is a prep phrase (is this possible?)
                        }
                        else
                        {
                            eParts[eParts.Length - 1] = partsWithPreps[0];
                            //No prep phrases.
                        }
                    }
                }

                string[] directObjects = ArrayExtensions.Tail(eParts);

                //List<HeadedPhrase> doNPs = new List<HeadedPhrase>();
                List <Chain> doPiChains = new List <Chain>();

                //Fancy foot work for when we have e ... ~... & that's all.
                string[] toUse;
                if (partsWithPreps != null)
                {
                    toUse = partsWithPreps.Where(x => x.StartCheck("e ")).ToArray();
                    directObjects[directObjects.Length - 1] = toUse[0];
                    toUse = directObjects;
                }
                else
                {
                    toUse = directObjects;
                }

                foreach (string directObject in toUse)
                {
                    if (directObject.Length <= 2)
                    {
                        throw new TpParseException("This is a degenerate e phrase, i.e. it is only e or e space. Missing a ni, e.g. e ni: possibly. ref: " + liPart);
                    }
                    string eFree  = directObject.Substring(2);
                    Chain  phrase = ProcessPiChain(eFree);
                    doPiChains.Add(phrase);
                }
                directObjectChain = new ComplexChain(Particles.e, doPiChains.ToArray());

                if (partsWithPreps != null)
                {
                    prepositionalChain = ProcessPrepositionalPhrases(partsWithPreps).ToArray();
                }
            }
            else
            {
                //Intransitives & Predictates

                string[] ppParts = Splitters.SplitOnPrepositions(liPart);

                if (ppParts.Length == 0) //Excect at least "li verb" or "li noun"
                {
                    throw new TpParseException("Whoa, got " + ppParts.Length + " parts for " + liPart);
                }

                if (Punctuation.ContainsPunctuation(ppParts[0]))
                {
                    throw new TpParseException("This has punctuation, may fail to parse : " + ppParts[0]);
                }
                string[] verbPhraseParts = pu.WordsPunctuationAndCompounds(ppParts[0]);

                if (!Token.CheckIsParticle(verbPhraseParts[0]))
                {
                    throw new TpSyntaxException("uh-oh not a particle: " + verbPhraseParts[0] + " from " + liPart);
                }
                verbPhraseParticle = new Particle(verbPhraseParts[0]);


                if (verbPhraseParts.Length > 1)
                {
                    //0:li 1:xxx 2:np...
                    if (verbPhraseParts[1].ContainsCheck("XXXXZiXXXX"))
                    {
                        //Make it go away. Confuses other parsers and will be picked up by container object.
                        verbPhraseParts = ArrayExtensions.Tail(verbPhraseParts);

                        //piPredicate
                        ComplexChain phrase = new ComplexChain(Particles.en,
                                                               new[] {
                            ProcessPiChain(String.Join(" ", ArrayExtensions.Tail(verbPhraseParts)))
                        });

                        piPredicate = new PiPredicate(Particles.pi, phrase);
                    }
                    else if (verbPhraseParts.Any(x => x == "pi"))
                    {
                        //nominal predicate
                        nominalPredicate = new ComplexChain(Particles.en,
                                                            new[] {
                            ProcessPiChain(String.Join(" ", ArrayExtensions.Tail(verbPhraseParts)))
                        }
                                                            );
                    }
                    else
                    {
                        verbPhrase = VerbPhraseParser(ArrayExtensions.Tail(verbPhraseParts));
                    }
                }


                string[] prepositions = ArrayExtensions.Tail(ppParts);

                if (prepositions.Length != 0)
                {
                    List <PrepositionalPhrase> pChains = new List <PrepositionalPhrase>();
                    foreach (string pp in prepositions)
                    {
                        string[] phraseParts = pu.WordsPunctuationAndCompounds(pp);//Could contain particles.
                        string   preposition = phraseParts[0];
                        string[] tail        = ArrayExtensions.Tail(phraseParts);

                        if (tail.Length == 0)
                        {
                            //uh oh. This is an intransitive verb, like "ni li lon"
                            //HACK: Oh, this is so ugly (still sort of ugly)
                            verbPhrase = new VerbPhrase(new Word(preposition.Replace("~", "")));
                            //or a noun phrase.

                            continue;
                        }

                        PrepositionalPhrase foundPrepositionalPhrase = new PrepositionalPhrase(new Word(preposition), ProcessEnPiChain(String.Join(" ", tail)));
                        pChains.Add(foundPrepositionalPhrase);
                    }
                    if (pChains.Count > 0)
                    {
                        prepositionalChain = pChains.ToArray();
                    }
                    else
                    {
                        //We changed our mind about a phrase being a prep phrase. Turned out to be verb phrase or predicate.
                    }
                }
            }
            if (piPredicate != null)
            {
                return(new TpPredicate(verbPhraseParticle, piPredicate, prepositionalChain));
            }
            if (nominalPredicate == null)
            {
                return(new TpPredicate(verbPhraseParticle, verbPhrase, directObjectChain, prepositionalChain));
            }

            return(new TpPredicate(verbPhraseParticle, nominalPredicate, directObjectChain, prepositionalChain));
        }
 /// <summary>
 ///  Updates data for computing a new value of the criterion.
 /// </summary>
 /// <param name="chain">
 /// A new chain.
 /// </param>
 /// <param name="alphabet">
 /// A new alphabet.
 /// </param>
 public void Renew(ComplexChain chain, FrequencyDictionary alphabet)
 {
     this.chain = chain;
     this.alphabet = alphabet;
 }