public NotenizerDependency(TypedDependency typedDependency)
 {
     _dependent = new NotenizerWord(typedDependency.dep());
     _governor = new NotenizerWord(typedDependency.gov());
     _relation = new NotenizerRelation(typedDependency.reln());
     _originalDependency = typedDependency;
 }
        private bool AreWordSeparatedInSentence(TypedDependency relation, List <TypedDependency> dependencies)
        {
            var btwCount = dependencies
                           .Select(d => d.Dep().Index())
                           .Distinct()
                           .Count(d => (relation.Gov().Index() < d && d < relation.Dep().Index()) ||
                                  (relation.Dep().Index() < d && d < relation.Gov().Index()));

            return(Math.Abs(relation.Gov().Index() - relation.Dep().Index()) - 1 > btwCount);
        }
Beispiel #3
0
        //was not implemented
        //public int GetDistanceFromChunkLimit()
        //{
        //    return 0;
        //}

        private IndexedWord GetRoot()
        {
            for (var iter = NounPhrase.Dependencies.iterator(); iter.hasNext();)
            {
                TypedDependency var = (TypedDependency)iter.next();

                if (var.reln().getShortName() == "root")
                {
                    return(var.dep());
                }
            }

            return(null);
        }
Beispiel #4
0
        public bool IsChildOfRoot()
        {
            IndexedWord root = GetRoot();

            for (var iter = NounPhrase.Dependencies.iterator(); iter.hasNext();)
            {
                TypedDependency var = (TypedDependency)iter.next();

                if (var.gov().Equals(root) && NounPhrase.PhraseArray.Contains(var.dep().word()))
                {
                    return(true);
                }
            }

            return(false);
        }
Beispiel #5
0
        public bool IsConnectedToSentiment()
        {
            for (var iter = NounPhrase.Dependencies.iterator(); iter.hasNext();)
            {
                TypedDependency var = (TypedDependency)iter.next();

                var dep = var.dep();
                var gov = var.gov();

                if ((NounPhrase.PhraseArray.Contains(dep.word()) && sentimentLexicon.GetSentiment(gov.word()) != 0) ||
                    (NounPhrase.PhraseArray.Contains(gov.word()) && sentimentLexicon.GetSentiment(dep.word()) != 0))
                {
                    return(true);
                }
            }

            return(false);
        }
Beispiel #6
0
            public virtual SemanticGraph Apply(string line)
            {
                if (line == null)
                {
                    return(null);
                }
                IFunction <string, IndexedWord> func     = new CoNLLUDocumentReader.WordProcessor();
                ObjectBank <IndexedWord>        words    = ObjectBank.GetLineIterator(new StringReader(line), func);
                IList <IndexedWord>             wordList = new List <IndexedWord>(words);
                IList <IndexedWord>             sorted   = new List <IndexedWord>(wordList.Count);
                IList <string> comments = new LinkedList <string>();

                /* Increase the line number in case there are comments before the actual sentence
                 * and add them to the list of comments. */
                wordList.Stream().Filter(null).ForEach(null);
                wordList.Stream().Filter(null).Sorted(byIndex.ThenComparing(byType)).ForEach(null);
                IList <IndexedWord> sortedTokens = new List <IndexedWord>(wordList.Count);

                sorted.Stream().Filter(null).Filter(null).ForEach(null);
                sorted.Stream().Filter(null).Filter(null).ForEach(null);
                /* Construct a semantic graph. */
                IList <TypedDependency> deps = new List <TypedDependency>(sorted.Count);
                IntPair tokenSpan            = null;
                string  originalToken        = null;

                foreach (IndexedWord word in sorted)
                {
                    lineNumberCounter++;
                    if (word.ContainsKey(typeof(CoreAnnotations.CoNLLUTokenSpanAnnotation)))
                    {
                        tokenSpan     = word.Get(typeof(CoreAnnotations.CoNLLUTokenSpanAnnotation));
                        originalToken = word.Word();
                    }
                    else
                    {
                        /* Deal with multiword tokens. */
                        if (tokenSpan != null && tokenSpan.GetTarget() >= word.Index())
                        {
                            word.SetOriginalText(originalToken);
                            word.Set(typeof(CoreAnnotations.CoNLLUTokenSpanAnnotation), tokenSpan);
                        }
                        else
                        {
                            tokenSpan     = null;
                            originalToken = null;
                        }
                        Dictionary <string, string> extraDeps = word.Get(typeof(CoreAnnotations.CoNLLUSecondaryDepsAnnotation));
                        if (extraDeps.IsEmpty())
                        {
                            int govIdx = word.Get(typeof(CoreAnnotations.CoNLLDepParentIndexAnnotation));
                            Pair <IndexedWord, GrammaticalRelation> govReln = GetGovAndReln(govIdx, 0, word, word.Get(typeof(CoreAnnotations.CoNLLDepTypeAnnotation)), sortedTokens);
                            IndexedWord         gov  = govReln.First();
                            GrammaticalRelation reln = govReln.Second();
                            TypedDependency     dep  = new TypedDependency(reln, gov, word);
                            word.Set(typeof(CoreAnnotations.LineNumberAnnotation), lineNumberCounter);
                            deps.Add(dep);
                        }
                        else
                        {
                            foreach (string extraGovIdxStr in extraDeps.Keys)
                            {
                                if (extraGovIdxStr.Contains("."))
                                {
                                    string[] indexParts  = extraGovIdxStr.Split("\\.");
                                    int      extraGovIdx = System.Convert.ToInt32(indexParts[0]);
                                    int      copyCount   = System.Convert.ToInt32(indexParts[1]);
                                    Pair <IndexedWord, GrammaticalRelation> govReln = GetGovAndReln(extraGovIdx, copyCount, word, extraDeps[extraGovIdxStr], sortedTokens);
                                    IndexedWord         gov  = govReln.First();
                                    GrammaticalRelation reln = govReln.Second();
                                    TypedDependency     dep  = new TypedDependency(reln, gov, word);
                                    dep.SetExtra();
                                    deps.Add(dep);
                                }
                                else
                                {
                                    int extraGovIdx = System.Convert.ToInt32(extraGovIdxStr);
                                    int mainGovIdx  = word.Get(typeof(CoreAnnotations.CoNLLDepParentIndexAnnotation)) != null?word.Get(typeof(CoreAnnotations.CoNLLDepParentIndexAnnotation)) : -1;

                                    Pair <IndexedWord, GrammaticalRelation> govReln = GetGovAndReln(extraGovIdx, 0, word, extraDeps[extraGovIdxStr], sortedTokens);
                                    IndexedWord         gov  = govReln.First();
                                    GrammaticalRelation reln = govReln.Second();
                                    TypedDependency     dep  = new TypedDependency(reln, gov, word);
                                    if (extraGovIdx != mainGovIdx)
                                    {
                                        dep.SetExtra();
                                    }
                                    deps.Add(dep);
                                }
                            }
                        }
                    }
                }
                lineNumberCounter++;
                SemanticGraph sg = new SemanticGraph(deps);

                comments.ForEach(null);
                return(sg);
            }
        //      collapseMultiwordPreps(list);
        private static void CollapsePrepAndPoss(ICollection <TypedDependency> list)
        {
            ICollection <TypedDependency> newTypedDeps = new List <TypedDependency>();
            // Construct a map from words to the set of typed
            // dependencies in which the word appears as governor.
            IDictionary <IndexedWord, ICollection <TypedDependency> > map = Generics.NewHashMap();

            foreach (TypedDependency typedDep in list)
            {
                if (!map.Contains(typedDep.Gov()))
                {
                    map[typedDep.Gov()] = Generics.NewHashSet <TypedDependency>();
                }
                map[typedDep.Gov()].Add(typedDep);
            }
            //log.info("here's the map: " + map);
            foreach (TypedDependency td1 in list)
            {
                if (td1.Reln() != GrammaticalRelation.Kill)
                {
                    IndexedWord td1Dep    = td1.Dep();
                    string      td1DepPOS = td1Dep.Tag();
                    // find all other typedDeps having our dep as gov
                    ICollection <TypedDependency> possibles = map[td1Dep];
                    if (possibles != null)
                    {
                        // look for the "second half"
                        foreach (TypedDependency td2 in possibles)
                        {
                            // TreeGraphNode td2Dep = td2.dep();
                            // String td2DepPOS = td2Dep.parent().value();
                            if (td1.Reln() == GrammaticalRelation.Dependent && td2.Reln() == GrammaticalRelation.Dependent && td1DepPOS.Equals("P"))
                            {
                                GrammaticalRelation td3reln = UniversalChineseGrammaticalRelations.ValueOf(td1Dep.Value());
                                if (td3reln == null)
                                {
                                    td3reln = GrammaticalRelation.ValueOf(Language.UniversalChinese, td1Dep.Value());
                                }
                                TypedDependency td3 = new TypedDependency(td3reln, td1.Gov(), td2.Dep());
                                //log.info("adding: " + td3);
                                newTypedDeps.Add(td3);
                                td1.SetReln(GrammaticalRelation.Kill);
                                // remember these are "used up"
                                td2.SetReln(GrammaticalRelation.Kill);
                            }
                        }
                        // remember these are "used up"
                        // Now we need to see if there any TDs that will be "orphaned"
                        // by this collapse.  Example: if we have:
                        //   dep(drew, on)
                        //   dep(on, book)
                        //   dep(on, right)
                        // the first two will be collapsed to on(drew, book), but then
                        // the third one will be orphaned, since its governor no
                        // longer appears.  So, change its governor to 'drew'.
                        if (td1.Reln().Equals(GrammaticalRelation.Kill))
                        {
                            foreach (TypedDependency td2_1 in possibles)
                            {
                                if (!td2_1.Reln().Equals(GrammaticalRelation.Kill))
                                {
                                    //log.info("td1 & td2: " + td1 + " & " + td2);
                                    td2_1.SetGov(td1.Gov());
                                }
                            }
                        }
                    }
                }
            }
            // now copy remaining unkilled TDs from here to new
            foreach (TypedDependency td in list)
            {
                if (!td.Reln().Equals(GrammaticalRelation.Kill))
                {
                    newTypedDeps.Add(td);
                }
            }
            list.Clear();
            // forget all (esp. killed) TDs
            Sharpen.Collections.AddAll(list, newTypedDeps);
        }
        /// <summary>
        /// Collapse 3-word preposition of the following format:
        /// This will be the case when the preposition is analyzed as a NP
        /// prep(gov, mwp0) 
        /// X(mwp0,mwp1)
        /// X(mwp1,mwp2)
        /// pobj|pcomp(mwp2, compl)
        /// -> prep_mwp[0]_mwp[1]_mwp[2](gov, compl)
        /// 
        /// It also takes flat annotation into account:
        /// prep(gov,mwp0)
        /// X(mwp0,mwp1)
        /// X(mwp0,mwp2)
        /// pobj|pcomp(mwp0, compl)
        /// -> prep_mwp[0]_mwp[1]_mwp[2](gov, compl)
        /// </summary>
        /// <param name="list">List of typedDependencies to work on</param>
        private static void Collapse3Wp(List<TypedDependency> list)
        {
            var newTypedDeps = new List<TypedDependency>();

            // first, loop over the prepositions for NP annotation
            foreach (string[] mwp in ThreewordPreps)
            {
                newTypedDeps.Clear();

                IndexedWord mwp0 = null;
                IndexedWord mwp1 = null;
                IndexedWord mwp2 = null;

                TypedDependency dep1 = null;
                TypedDependency dep2 = null;

                // first find the first part of the 3word preposition: dep(mpw[0], mwp[1])
                // the two words should be next to another in the sentence (difference of
                // indexes = 1)

                foreach (TypedDependency td in list)
                {
                    if (td.Gov.Value().Equals(mwp[0], StringComparison.InvariantCultureIgnoreCase)
                        && td.Dep.Value().Equals(mwp[1], StringComparison.InvariantCultureIgnoreCase)
                        && Math.Abs(td.Gov.Index() - td.Dep.Index()) == 1)
                    {
                        mwp0 = td.Gov;
                        mwp1 = td.Dep;
                        dep1 = td;
                    }
                }

                // find the second part of the 3word preposition: dep(mpw[1], mwp[2])
                // the two words should be next to another in the sentence (difference of
                // indexes = 1)

                foreach (TypedDependency td in list)
                {
                    if (td.Gov.Equals(mwp1) &&
                        td.Dep.Value().Equals(mwp[2], StringComparison.InvariantCultureIgnoreCase)
                        && Math.Abs(td.Gov.Index() - td.Dep.Index()) == 1)
                    {
                        mwp2 = td.Dep;
                        dep2 = td;
                    }
                }

                if (dep1 != null && dep2 != null)
                {

                    // now search for prep(gov, mwp0)
                    IndexedWord governor = null;
                    TypedDependency prep = null;
                    foreach (TypedDependency td1 in list)
                    {
                        if (td1.Reln == EnglishGrammaticalRelations.PrepositionalModifier && td1.Dep.Equals(mwp0))
                        {
// we
                            // found
                            // prep(gov,
                            // mwp0)
                            prep = td1;
                            governor = prep.Gov;
                        }
                    }

                    // search for the complement: pobj|pcomp(mwp2,X)

                    TypedDependency pobj = null;
                    TypedDependency newtd = null;
                    foreach (TypedDependency td2 in list)
                    {
                        if (td2.Reln == EnglishGrammaticalRelations.PrepositionalObject && td2.Gov.Equals(mwp2))
                        {
                            pobj = td2;
                            // create the new gr relation
                            GrammaticalRelation gr =
                                EnglishGrammaticalRelations.GetPrep(mwp[0] + '_' + mwp[1] + '_' + mwp[2]);
                            if (governor != null)
                            {
                                newtd = new TypedDependency(gr, governor, pobj.Dep);
                            }
                        }
                        if (td2.Reln == EnglishGrammaticalRelations.PrepositionalComplement && td2.Gov.Equals(mwp2))
                        {
                            pobj = td2;
                            // create the new gr relation
                            GrammaticalRelation gr =
                                EnglishGrammaticalRelations.GetPrepC(mwp[0] + '_' + mwp[1] + '_' + mwp[2]);
                            if (governor != null)
                            {
                                newtd = new TypedDependency(gr, governor, pobj.Dep);
                            }
                        }
                    }

                    // only if we found the governor and complement parts, set to KILL and
                    // remove
                    // and add the new one
                    if (prep != null && pobj != null && newtd != null)
                    {
                        prep.Reln = GrammaticalRelation.Kill;
                        dep1.Reln = GrammaticalRelation.Kill;
                        dep2.Reln = GrammaticalRelation.Kill;
                        pobj.Reln = GrammaticalRelation.Kill;
                        newTypedDeps.Add(newtd);

                        // now remove typed dependencies with reln "kill"
                        // and promote possible orphans
                        foreach (TypedDependency td1 in list)
                        {
                            if (td1.Reln != GrammaticalRelation.Kill)
                            {
                                if (td1.Gov.Equals(mwp0) || td1.Gov.Equals(mwp1) || td1.Gov.Equals(mwp2))
                                {
                                    td1.Gov = governor;
                                }
                                if (!newTypedDeps.Contains(td1))
                                {
                                    newTypedDeps.Add(td1);
                                }
                            }
                        }
                        list.Clear();
                        list.AddRange(newTypedDeps);
                    }
                }
            }

            // second, loop again looking at flat annotation
            foreach (string[] mwp in ThreewordPreps)
            {
                newTypedDeps.Clear();

                IndexedWord mwp0 = null;
                IndexedWord mwp1 = null;
                IndexedWord mwp2 = null;

                TypedDependency dep1 = null;
                TypedDependency dep2 = null;

                // first find the first part of the 3word preposition: dep(mpw[0], mwp[1])
                // the two words should be next to another in the sentence (difference of
                // indexes = 1)
                foreach (TypedDependency td in list)
                {
                    if (td.Gov.Value().Equals(mwp[0], StringComparison.InvariantCultureIgnoreCase)
                        && td.Dep.Value().Equals(mwp[1], StringComparison.InvariantCultureIgnoreCase)
                        && Math.Abs(td.Gov.Index() - td.Dep.Index()) == 1)
                    {
                        mwp0 = td.Gov;
                        mwp1 = td.Dep;
                        dep1 = td;
                    }
                }

                // find the second part of the 3word preposition: dep(mpw[0], mwp[2])
                // the two words should be one word apart in the sentence (difference of
                // indexes = 2)
                foreach (TypedDependency td in list)
                {
                    if (td.Gov.Equals(mwp0) &&
                        td.Dep.Value().Equals(mwp[2], StringComparison.InvariantCultureIgnoreCase)
                        && Math.Abs(td.Gov.Index() - td.Dep.Index()) == 2)
                    {
                        mwp2 = td.Dep;
                        dep2 = td;
                    }
                }

                if (dep1 != null && dep2 != null)
                {

                    // now search for prep(gov, mwp0)
                    IndexedWord governor = null;
                    TypedDependency prep = null;
                    foreach (TypedDependency td1 in list)
                    {
                        if (td1.Dep.Equals(mwp0) && td1.Reln == EnglishGrammaticalRelations.PrepositionalModifier)
                        {
// we
                            // found
                            // prep(gov,
                            // mwp0)
                            prep = td1;
                            governor = prep.Gov;
                        }
                    }

                    // search for the complement: pobj|pcomp(mwp0,X)

                    TypedDependency pobj = null;
                    TypedDependency newtd = null;
                    foreach (TypedDependency td2 in list)
                    {
                        if (td2.Gov.Equals(mwp0) && td2.Reln == EnglishGrammaticalRelations.PrepositionalObject)
                        {
                            pobj = td2;
                            // create the new gr relation
                            GrammaticalRelation gr =
                                EnglishGrammaticalRelations.GetPrep(mwp[0] + '_' + mwp[1] + '_' + mwp[2]);
                            if (governor != null)
                            {
                                newtd = new TypedDependency(gr, governor, pobj.Dep);
                            }
                        }
                        if (td2.Gov.Equals(mwp0) && td2.Reln == EnglishGrammaticalRelations.PrepositionalComplement)
                        {
                            pobj = td2;
                            // create the new gr relation
                            GrammaticalRelation gr =
                                EnglishGrammaticalRelations.GetPrepC(mwp[0] + '_' + mwp[1] + '_' + mwp[2]);
                            if (governor != null)
                            {
                                newtd = new TypedDependency(gr, governor, pobj.Dep);
                            }
                        }
                    }

                    // only if we found the governor and complement parts, set to KILL and
                    // remove
                    // and add the new one
                    if (prep != null && pobj != null && newtd != null)
                    {
                        prep.Reln = GrammaticalRelation.Kill;
                        dep1.Reln = GrammaticalRelation.Kill;
                        dep2.Reln = GrammaticalRelation.Kill;
                        pobj.Reln = GrammaticalRelation.Kill;
                        newTypedDeps.Add(newtd);

                        // now remove typed dependencies with reln "kill"
                        // and promote possible orphans
                        foreach (TypedDependency td1 in list)
                        {
                            if (td1.Reln != GrammaticalRelation.Kill)
                            {
                                if (td1.Gov.Equals(mwp0) || td1.Gov.Equals(mwp1) || td1.Gov.Equals(mwp2))
                                {
                                    td1.Gov = governor;
                                }
                                if (!newTypedDeps.Contains(td1))
                                {
                                    newTypedDeps.Add(td1);
                                }
                            }
                        }
                        list.Clear();
                        list.AddRange(newTypedDeps);
                    }
                }
            }
        }
        private static void CollapsePrepAndPoss(List<TypedDependency> list)
        {

            // Man oh man, how gnarly is the logic of this method....
            var newTypedDeps = new List<TypedDependency>();

            // Construct a map from tree nodes to the set of typed
            // dependencies in which the node appears as governor.
            // cdm: could use CollectionValuedMap here!
            var map = new Dictionary<IndexedWord, Util.SortedSet<TypedDependency>>();
            var vmod = new List<IndexedWord>();

            foreach (TypedDependency typedDep in list)
            {
                if (!map.ContainsKey(typedDep.Gov))
                {
                    map.Add(typedDep.Gov, new TreeSet<TypedDependency>());
                }
                map[typedDep.Gov].Add(typedDep);

                if (typedDep.Reln == EnglishGrammaticalRelations.VerbalModifier)
                {
                    // look for aux deps which indicate this was a to-be verb
                    bool foundAux = false;
                    foreach (TypedDependency auxDep in list)
                    {
                        if (auxDep.Reln != EnglishGrammaticalRelations.AuxModifier)
                        {
                            continue;
                        }
                        if (!auxDep.Gov.Equals(typedDep.Dep) ||
                            !auxDep.Dep.Value().Equals("to", StringComparison.InvariantCultureIgnoreCase))
                        {
                            continue;
                        }
                        foundAux = true;
                        break;
                    }
                    if (!foundAux)
                    {
                        vmod.Add(typedDep.Dep);
                    }
                }
            }

            // Do preposition conjunction interaction for
            // governor p NP and p NP case ... a lot of special code cdm jan 2006

            foreach (TypedDependency td1 in list)
            {
                if (td1.Reln != EnglishGrammaticalRelations.PrepositionalModifier)
                {
                    continue;
                }
                if (td1.Reln == GrammaticalRelation.Kill)
                {
                    continue;
                }

                IndexedWord td1Dep = td1.Dep;
                Util.SortedSet<TypedDependency> possibles = map[td1Dep];
                if (possibles == null)
                {
                    continue;
                }

                // look for the "second half"

                // unique: the head prep and whether it should be pobj
                Tuple<TypedDependency, bool> prepDep = null;
                TypedDependency ccDep = null; // treat as unique
                // list of dep and prepOtherDep and pobj (or  pcomp)
                var conjs = new List<Tuple<TypedDependency, TypedDependency, bool>>();
                Set<TypedDependency> otherDtrs = new TreeSet<TypedDependency>();

                // first look for a conj(prep, prep) (there might be several conj relations!!!)
                bool samePrepositionInEachConjunct = true;
                int conjIndex = -1;
                foreach (TypedDependency td2 in possibles)
                {
                    if (td2.Reln == EnglishGrammaticalRelations.Conjunct)
                    {
                        IndexedWord td2Dep = td2.Dep;
                        string td2DepPOS = td2Dep.Tag();
                        if (td2DepPOS == PartsOfSpeech.PrepositionOrSubordinateConjunction 
                            || td2DepPOS == PartsOfSpeech.To)
                        {
                            samePrepositionInEachConjunct = samePrepositionInEachConjunct &&
                                                            td2Dep.Value().Equals(td1Dep.Value());
                            Set<TypedDependency> possibles2 = map[td2Dep];
                            bool pobj = true; // default of collapsing preposition is prep_
                            TypedDependency prepOtherDep = null;
                            if (possibles2 != null)
                            {
                                foreach (TypedDependency td3 in possibles2)
                                {
                                    IndexedWord td3Dep = td3.Dep;
                                    string td3DepPOS = td3Dep.Tag();
                                    // CDM Mar 2006: I put in disjunction here when I added in
                                    // PREPOSITIONAL_OBJECT. If it catches all cases, we should
                                    // be able to delete the DEPENDENT disjunct
                                    // maybe better to delete the DEPENDENT disjunct - it creates
                                    // problem with multiple prep (mcdm)
                                    if ((td3.Reln == EnglishGrammaticalRelations.PrepositionalObject ||
                                         td3.Reln == EnglishGrammaticalRelations.PrepositionalComplement) &&
                                        (!(td3DepPOS == PartsOfSpeech.PrepositionOrSubordinateConjunction || td3DepPOS == PartsOfSpeech.To)) && prepOtherDep == null)
                                    {
                                        prepOtherDep = td3;
                                        if (td3.Reln == EnglishGrammaticalRelations.PrepositionalComplement)
                                        {
                                            pobj = false;
                                        }
                                    }
                                    else
                                    {
                                        otherDtrs.Add(td3);
                                    }
                                }
                            }
                            if (conjIndex < td2Dep.Index())
                            {
                                conjIndex = td2Dep.Index();
                            }
                            conjs.Add(new Tuple<TypedDependency, TypedDependency, Boolean>(td2, prepOtherDep, pobj));
                        }
                    }
                } // end td2:possibles

                if (!conjs.Any())
                {
                    continue;
                }

                // if we have a conj under a preposition dependency, we look for the other
                // parts

                string td1DepPOS = td1Dep.Tag();
                foreach (TypedDependency td2 in possibles)
                {
                    // we look for the cc linked to this conjDep
                    // the cc dep must have an index smaller than the dep of conjDep
                    if (td2.Reln == EnglishGrammaticalRelations.Coordination && td2.Dep.Index() < conjIndex)
                    {
                        ccDep = td2;
                    }
                    else
                    {
                        IndexedWord td2Dep = td2.Dep;
                        string td2DepPOS = td2Dep.Tag();
                        if ((td2.Reln == GrammaticalRelation.Dependent ||
                             td2.Reln == EnglishGrammaticalRelations.PrepositionalObject ||
                             td2.Reln == EnglishGrammaticalRelations.PrepositionalComplement) &&
                            (PartsOfSpeech.PrepositionOrSubordinateConjunction == td1DepPOS || PartsOfSpeech.To == td1DepPOS
                            || PartsOfSpeech.VerbGerundOrPresentParticiple == td1DepPOS) 
                            && prepDep == null 
                            && (!(PartsOfSpeech.Adverb == td2DepPOS || PartsOfSpeech.PrepositionOrSubordinateConjunction == td2DepPOS || PartsOfSpeech.To == td2DepPOS)))
                        {
                            // same index trick, in case we have multiple deps
                            // I deleted this to see if it helped [cdm Jan 2010] &&
                            // td2.dep().index() < index)
                            prepDep = new Tuple<TypedDependency, Boolean>(td2,
                                td2.Reln != EnglishGrammaticalRelations.PrepositionalComplement);
                        }
                        else if (!inConjDeps(td2, conjs))
                        {
                            // don't want to add the conjDep
                            // again!
                            otherDtrs.Add(td2);
                        }
                    }
                }

                if (prepDep == null || ccDep == null)
                {
                    continue; // we can't deal with it in the hairy prep/conj interaction
                    // case!
                }
                
                // check if we have the same prepositions in the conjunction
                if (samePrepositionInEachConjunct)
                {
                    // conjDep != null && prepOtherDep !=
                    // null &&
                    // OK, we have a conjunction over parallel PPs: Fred flew to Greece and
                    // to Serbia.
                    GrammaticalRelation reln = DeterminePrepRelation(map, vmod, td1, td1, prepDep.Item2);

                    var tdNew = new TypedDependency(reln, td1.Gov, prepDep.Item1.Dep);
                    newTypedDeps.Add(tdNew);
                    td1.Reln = GrammaticalRelation.Kill; // remember these are "used up"
                    prepDep.Item1.Reln = GrammaticalRelation.Kill;
                    ccDep.Reln = GrammaticalRelation.Kill;

                    foreach (Tuple<TypedDependency, TypedDependency, Boolean> trip in conjs)
                    {
                        TypedDependency conjDep = trip.Item1;
                        TypedDependency prepOtherDep = trip.Item2;
                        if (prepOtherDep == null)
                        {
                            // CDM July 2010: I think this should only ever happen if there is a
                            // misparse, but it has happened in such circumstances. You have
                            // something like (PP in or in (NP Serbia)), with the two
                            // prepositions the same. We just clean up the mess.
                            ccDep.Reln = GrammaticalRelation.Kill;
                        }
                        else
                        {
                            var tdNew2 = new TypedDependency(ConjValue(ccDep.Dep.Value()),
                                prepDep.Item1.Dep, prepOtherDep.Dep);
                            newTypedDeps.Add(tdNew2);
                            prepOtherDep.Reln = GrammaticalRelation.Kill;
                        }
                        conjDep.Reln = GrammaticalRelation.Kill;
                    }

                    // promote dtrs that would be orphaned
                    foreach (TypedDependency otd in otherDtrs)
                    {
                        otd.Gov = td1.Gov;
                    }

                    // Now we need to see if there are any TDs that will be "orphaned"
                    // by this collapse. Example: if we have:
                    // dep(drew, on)
                    // dep(on, book)
                    // dep(on, right)
                    // the first two will be collapsed to on(drew, book), but then
                    // the third one will be orphaned, since its governor no
                    // longer appears. So, change its governor to 'drew'.
                    // CDM Feb 2010: This used to not move COORDINATION OR CONJUNCT, but now
                    // it does, since they're not automatically deleted
                    // Some things in possibles may have already been changed, so check gov
                    foreach (TypedDependency td2 in possibles)
                    {
                        if (td2.Reln != GrammaticalRelation.Kill && td2.Gov.Equals(td1.Dep))
                        {
                            // && td2.reln()
                            // != COORDINATION
                            // && td2.reln()
                            // != CONJUNCT
                            td2.Gov = td1.Gov;
                        }
                    }
                    continue; // This one has been dealt with successfully
                } // end same prepositions

                // case of "Lufthansa flies to and from Serbia". Make it look like next
                // case :-)
                // that is, the prepOtherDep should be the same as prepDep !
                var newConjList = new List<Tuple<TypedDependency, TypedDependency, bool>>();
                foreach (Tuple<TypedDependency, TypedDependency, Boolean> trip in conjs)
                {
                    if (trip.Item1 != null && trip.Item2 == null)
                    {
                        /*trip.Item2 = new TypedDependency(prepDep.Item1.reln(), trip.Item1.dep(), prepDep.Item1.dep());
          trip.Item3 = prepDep.Item2;*/
                        newConjList.Add(new Tuple<TypedDependency, TypedDependency, bool>(trip.Item1,
                            new TypedDependency(prepDep.Item1.Reln, trip.Item1.Dep, prepDep.Item1.Dep),
                            prepDep.Item2));
                    }
                    else
                    {
                        newConjList.Add(trip);
                    }
                }
                conjs = newConjList;

                // we have two different prepositions in the conjunction
                // in this case we need to add a node
                // "Bill jumped over the fence and through the hoop"
                // prep_over(jumped, fence)
                // conj_and(jumped, jumped)
                // prep_through(jumped, hoop)

                GrammaticalRelation _reln = DeterminePrepRelation(map, vmod, td1, td1, prepDep.Item2);
                var _tdNew = new TypedDependency(_reln, td1.Gov, prepDep.Item1.Dep);
                newTypedDeps.Add(_tdNew);

                td1.Reln = GrammaticalRelation.Kill; // remember these are "used up"
                prepDep.Item1.Reln = GrammaticalRelation.Kill;
                ccDep.Reln = GrammaticalRelation.Kill;
                // so far we added the first prep grammatical relation

                int copyNumber = 1;
                foreach (Tuple<TypedDependency, TypedDependency, bool> trip in conjs)
                {
                    TypedDependency conjDep = trip.Item1;
                    TypedDependency prepOtherDep = trip.Item2;
                    bool pobj = trip.Item3;
                    // OK, we have a conjunction over different PPs
                    // we create a new node;
                    // in order to make a distinction between the original node and its copy
                    // we add a "copy" entry in the CoreLabel
                    // existence of copy key is checked at printing (ToString method of
                    // TypedDependency)
                    IndexedWord label = td1.Gov.MakeCopy(copyNumber);
                    copyNumber++;

                    // now we add the conjunction relation between td1.gov and the copy
                    // the copy has the same label as td1.gov() but is another TreeGraphNode
                    var tdNew2 = new TypedDependency(ConjValue(ccDep.Dep.Value()), td1.Gov, label);
                    newTypedDeps.Add(tdNew2);

                    // now we still need to add the second prep grammatical relation
                    // between the copy and the dependent of the prepOtherDep node
                    GrammaticalRelation reln2 = DeterminePrepRelation(map, vmod, conjDep, td1, pobj);
                    var tdNew3 = new TypedDependency(reln2, label, prepOtherDep.Dep);
                    newTypedDeps.Add(tdNew3);

                    conjDep.Reln = GrammaticalRelation.Kill;
                    prepOtherDep.Reln = GrammaticalRelation.Kill;

                    // promote dtrs that would be orphaned
                    foreach (TypedDependency otd in otherDtrs)
                    {
                        // special treatment for prepositions: the original relation is
                        // likely to be a "dep" and we want this to be a "prep"
                        if (otd.Dep.Tag() == PartsOfSpeech.PrepositionOrSubordinateConjunction)
                        {
                            otd.Reln = EnglishGrammaticalRelations.PrepositionalModifier;
                        }
                        otd.Gov = td1.Gov;
                    }
                }

                // Now we need to see if there are any TDs that will be "orphaned" off
                // the first preposition
                // by this collapse. Example: if we have:
                // dep(drew, on)
                // dep(on, book)
                // dep(on, right)
                // the first two will be collapsed to on(drew, book), but then
                // the third one will be orphaned, since its governor no
                // longer appears. So, change its governor to 'drew'.
                // CDM Feb 2010: This used to not move COORDINATION OR CONJUNCT, but now
                // it does, since they're not automatically deleted
                foreach (TypedDependency td2 in possibles)
                {
                    if (td2.Reln != GrammaticalRelation.Kill)
                    {
                        // && td2.reln() != COORDINATION &&
                        // td2.reln() != CONJUNCT) {
                        td2.Gov = td1.Gov;
                    }
                }
                // end for different prepositions
            } // for TypedDependency td1 : list

            // below here is the single preposition/possessor basic case!!
            foreach (TypedDependency td1 in list)
            {
                if (td1.Reln == GrammaticalRelation.Kill)
                {
                    continue;
                }

                IndexedWord td1Dep = td1.Dep;
                string td1DepPOS = td1Dep.Tag();
                // find all other typedDeps having our dep as gov
                Set<TypedDependency> possibles = map[td1Dep];

                if (possibles != null &&
                    (td1.Reln == EnglishGrammaticalRelations.PrepositionalModifier ||
                     td1.Reln == EnglishGrammaticalRelations.PossessionModifier ||
                     td1.Reln == EnglishGrammaticalRelations.Conjunct))
                {

                    // look for the "second half"
                    bool pobj = true; // default for prep relation is prep_
                    foreach (TypedDependency td2 in possibles)
                    {
                        if (td2.Reln != EnglishGrammaticalRelations.Coordination &&
                            td2.Reln != EnglishGrammaticalRelations.Conjunct)
                        {

                            IndexedWord td2Dep = td2.Dep;
                            string td2DepPOS = td2Dep.Tag();
                            if ((td1.Reln == EnglishGrammaticalRelations.PossessionModifier ||
                                 td1.Reln == EnglishGrammaticalRelations.Conjunct))
                            {
                                if (td2.Reln == EnglishGrammaticalRelations.PossessiveModifier)
                                {
                                    if (! map.ContainsKey(td2Dep))
                                    {
                                        // if 's has no kids of its own (it shouldn't!)
                                        td2.Reln = GrammaticalRelation.Kill;
                                    }
                                }
                            }
                            else if ((td2.Reln == EnglishGrammaticalRelations.PrepositionalObject ||
                                      td2.Reln == EnglishGrammaticalRelations.PrepositionalComplement) &&
                                     (PartsOfSpeech.PrepositionOrSubordinateConjunction == td1DepPOS 
                                || PartsOfSpeech.To == td1DepPOS || PartsOfSpeech.VerbGerundOrPresentParticiple == td1DepPOS) &&
                                     (!(PartsOfSpeech.Adverb == td2DepPOS 
                                || PartsOfSpeech.PrepositionOrSubordinateConjunction == td2DepPOS || PartsOfSpeech.To == td2DepPOS)) &&
                                     !IsConjWithNoPrep(td2.Gov, possibles))
                            {
                                // we don't collapse preposition conjoined with a non-preposition
                                // to avoid disconnected constituents
                                // OK, we have a pair td1, td2 to collapse to td3

                                // check whether we are in a pcomp case:
                                if (td2.Reln == EnglishGrammaticalRelations.PrepositionalComplement)
                                {
                                    pobj = false;
                                }

                                GrammaticalRelation reln = DeterminePrepRelation(map, vmod, td1, td1, pobj);
                                var td3 = new TypedDependency(reln, td1.Gov, td2.Dep);
                                // add it to map to deal with recursive cases like "achieved this (PP (PP in part) with talent)"
                                map[td3.Gov].Add(td3);

                                newTypedDeps.Add(td3);
                                td1.Reln = GrammaticalRelation.Kill; // remember these are "used up"
                                td2.Reln = GrammaticalRelation.Kill; // remember these are "used up"
                            }
                        }
                    } // for TypedDependency td2
                }

                // Now we need to see if there are any TDs that will be "orphaned"
                // by this collapse. Example: if we have:
                // dep(drew, on)
                // dep(on, book)
                // dep(on, right)
                // the first two will be collapsed to on(drew, book), but then
                // the third one will be orphaned, since its governor no
                // longer appears. So, change its governor to 'drew'.
                // CDM Feb 2010: This used to not move COORDINATION OR CONJUNCT, but now
                // it does, since they're not automatically deleted
                if (possibles != null && td1.Reln == GrammaticalRelation.Kill)
                {
                    foreach (TypedDependency td2 in possibles)
                    {
                        if (td2.Reln != GrammaticalRelation.Kill)
                        {
                            // && td2.reln() != COORDINATION &&
                            // td2.reln() != CONJUNCT) {
                            td2.Gov = td1.Gov;
                        }
                    }
                }

            } // for TypedDependency td1

            // now remove typed dependencies with reln "kill" and add new ones.
            /*for (Iterator<TypedDependency> iter = list.iterator(); iter.hasNext();) {
      TypedDependency td = iter.next();
      if (td.reln() == KILL) {
        iter.remove();
      }
    }*/
            list.RemoveAll(td => td.Reln == GrammaticalRelation.Kill);
            list.AddRange(newTypedDeps);
        } // end collapsePrepAndPoss()
        /// <summary>
        /// Collapse multiword preposition of the following format:
        /// prep|advmod|dep|amod(gov, mwp0) dep(mpw0,mwp1) pobj|pcomp(mwp1, compl) or
        /// pobj|pcomp(mwp0, compl) -> prep_mwp0_mwp1(gov, compl)
        /// </summary>
        /// <param name="list">List of typedDependencies to work on</param>
        /// <param name="newTypedDeps">List of typedDependencies that we construct</param>
        /// <param name="strMwp0">First part of the multiword preposition to construct the collapsed preposition</param>
        /// <param name="strMwp1">Second part of the multiword preposition to construct the collapsed preposition</param>
        /// <param name="wMwp0">First part of the multiword preposition that we look for</param>
        /// <param name="wMwp1">Second part of the multiword preposition that we look for</param>
        private static void CollapseMultiWordPrep(List<TypedDependency> list, List<TypedDependency> newTypedDeps,
            string strMwp0, string strMwp1, string wMwp0, string wMwp1)
        {

            // first find the multiword_preposition: dep(mpw[0], mwp[1])
            // the two words should be next to another in the sentence (difference of
            // indexes = 1)
            IndexedWord mwp0 = null;
            IndexedWord mwp1 = null;
            TypedDependency dep = null;
            foreach (TypedDependency td in list)
            {
                if (td.Gov.Value().Equals(wMwp0, StringComparison.InvariantCultureIgnoreCase) &&
                    td.Dep.Value().Equals(wMwp1, StringComparison.InvariantCultureIgnoreCase) &&
                    Math.Abs(td.Gov.Index() - td.Dep.Index()) == 1)
                {
                    mwp0 = td.Gov;
                    mwp1 = td.Dep;
                    dep = td;
                }
            }

            if (mwp0 == null)
            {
                return;
            }

            // now search for prep|advmod|dep|amod(gov, mwp0)
            IndexedWord governor = null;
            TypedDependency prep = null;
            foreach (TypedDependency td1 in list)
            {
                if ((td1.Reln == EnglishGrammaticalRelations.PrepositionalModifier ||
                     td1.Reln == EnglishGrammaticalRelations.AdverbialModifier ||
                     td1.Reln == EnglishGrammaticalRelations.AdjectivalModifier ||
                     td1.Reln == GrammaticalRelation.Dependent ||
                     td1.Reln == EnglishGrammaticalRelations.MultiWordExpression) && td1.Dep.Equals(mwp0))
                {
                    // we found prep|advmod|dep|amod(gov, mwp0)
                    prep = td1;
                    governor = prep.Gov;
                }
            }

            if (prep == null)
            {
                return;
            }

            // search for the complement: pobj|pcomp(mwp1,X)
            // or for pobj|pcomp(mwp0,X)
            // There may be more than one in weird constructions; if there are several,
            // take the one with the LOWEST index!
            TypedDependency pobj = null;
            TypedDependency newtd = null;
            foreach (TypedDependency td2 in list)
            {
                if ((td2.Reln == EnglishGrammaticalRelations.PrepositionalObject ||
                     td2.Reln == EnglishGrammaticalRelations.PrepositionalComplement) &&
                    (td2.Gov.Equals(mwp1) || td2.Gov.Equals(mwp0)))
                {
                    if (pobj == null || pobj.Dep.Index() > td2.Dep.Index())
                    {
                        pobj = td2;
                        // create the new gr relation
                        GrammaticalRelation gr;
                        if (td2.Reln == EnglishGrammaticalRelations.PrepositionalComplement)
                        {
                            gr = EnglishGrammaticalRelations.GetPrepC(strMwp0 + '_' + strMwp1);
                        }
                        else
                        {
                            gr = EnglishGrammaticalRelations.GetPrep(strMwp0 + '_' + strMwp1);
                        }
                        if (governor != null)
                        {
                            newtd = new TypedDependency(gr, governor, pobj.Dep);
                        }
                    }
                }
            }

            if (pobj == null || newtd == null)
            {
                return;
            }

            // only if we found the three parts, set to KILL and remove
            // and add the new one
            // Necessarily from the above: prep != null, dep != null, pobj != null, newtd != null

            prep.Reln = GrammaticalRelation.Kill;
            dep.Reln = GrammaticalRelation.Kill;
            pobj.Reln = GrammaticalRelation.Kill;
            newTypedDeps.Add(newtd);

            // now remove typed dependencies with reln "kill"
            // and promote possible orphans
            foreach (TypedDependency td1 in list)
            {
                if (td1.Reln != GrammaticalRelation.Kill)
                {
                    if (td1.Gov.Equals(mwp0) || td1.Gov.Equals(mwp1))
                    {
                        // CDM: Thought of adding this in Jan 2010, but it causes
                        // conflicting relations tmod vs. pobj. Needs more thought
                        // maybe restrict pobj to first NP in PP, and allow tmod for a later
                        // one?
                        if (td1.Reln == EnglishGrammaticalRelations.TemporalModifier)
                        {
                            // special case when an extra NP-TMP is buried in a PP for
                            // "during the same period last year"
                            td1.Gov = pobj.Dep;
                        }
                        else
                        {
                            td1.Gov = governor;
                        }
                    }
                    if (!newTypedDeps.Contains(td1))
                    {
                        newTypedDeps.Add(td1);
                    }
                }
            }
            list.Clear();
            list.AddRange(newTypedDeps);
        }
        /// <summary>
        /// Collapse multi-words preposition of the following format: advmod|prt(gov,
        /// mwp[0]) prep(gov,mwp[1]) pobj|pcomp(mwp[1], compl) ->
        /// prep_mwp[0]_mwp[1](gov, compl)
        /// </summary>
        /// <param name="list">List of typedDependencies to work on</param>
        private static void Collapse2WpBis(List<TypedDependency> list)
        {
            var newTypedDeps = new List<TypedDependency>();

            foreach (string[] mwp in MultiwordPreps)
            {
                newTypedDeps.Clear();

                IndexedWord mwp0 = null;
                IndexedWord mwp1 = null;
                IndexedWord governor = null;

                TypedDependency prep = null;
                TypedDependency dep = null;
                TypedDependency pobj = null;
                TypedDependency newtd = null;

                // first find the first part of the multi_preposition: advmod|prt(gov, mwp[0])

                foreach (TypedDependency td in list)
                {
                    if (td.Dep.Value().Equals(mwp[0], StringComparison.InvariantCultureIgnoreCase)
                        &&
                        (td.Reln == EnglishGrammaticalRelations.PhrasalVerbParticle ||
                         td.Reln == EnglishGrammaticalRelations.AdverbialModifier
                         || td.Reln == GrammaticalRelation.Dependent ||
                         td.Reln == EnglishGrammaticalRelations.MultiWordExpression))
                    {
                        // we found advmod(gov, mwp0) or prt(gov, mwp0)
                        governor = td.Gov;
                        mwp0 = td.Dep;
                        dep = td;
                    }
                }

                // now search for the second part: prep(gov, mwp1)
                // the two words in the mwp should be next to another in the sentence
                // (difference of indexes = 1)

                if (mwp0 == null || governor == null)
                {
                    continue;
                }

                foreach (TypedDependency td1 in list)
                {
                    if (td1.Reln == EnglishGrammaticalRelations.PrepositionalModifier
                        && td1.Dep.Value().Equals(mwp[1], StringComparison.InvariantCultureIgnoreCase)
                        && Math.Abs(td1.Dep.Index() - mwp0.Index()) == 1 && td1.Gov.Equals(governor))
                    {
// we
                        // found
                        // prep(gov,
                        // mwp1)
                        mwp1 = td1.Dep;
                        prep = td1;
                    }
                }

                if (mwp1 == null)
                {
                    continue;
                }

                // search for the complement: pobj|pcomp(mwp1,X)
                foreach (TypedDependency td2 in list)
                {
                    if (td2.Reln == EnglishGrammaticalRelations.PrepositionalObject && td2.Gov.Equals(mwp1))
                    {
                        pobj = td2;
                        // create the new gr relation
                        GrammaticalRelation gr = EnglishGrammaticalRelations.GetPrep(mwp[0] + '_' + mwp[1]);
                        newtd = new TypedDependency(gr, governor, pobj.Dep);
                    }
                    if (td2.Reln == EnglishGrammaticalRelations.PrepositionalComplement && td2.Gov.Equals(mwp1))
                    {
                        pobj = td2;
                        // create the new gr relation
                        GrammaticalRelation gr = EnglishGrammaticalRelations.GetPrepC(mwp[0] + '_' + mwp[1]);
                        newtd = new TypedDependency(gr, governor, pobj.Dep);
                    }
                }

                if (pobj == null)
                {
                    return;
                }

                // only if we found the three parts, set to KILL and remove
                // and add the new one
                // now prep != null, pobj != null and newtd != null

                prep.Reln = GrammaticalRelation.Kill;
                dep.Reln = GrammaticalRelation.Kill;
                pobj.Reln = GrammaticalRelation.Kill;
                newTypedDeps.Add(newtd);

                // now remove typed dependencies with reln "kill"
                // and promote possible orphans
                foreach (TypedDependency td1 in list)
                {
                    if (td1.Reln != GrammaticalRelation.Kill)
                    {
                        if (td1.Gov.Equals(mwp0) || td1.Gov.Equals(mwp1))
                        {
                            td1.Gov = governor;
                        }
                        if (!newTypedDeps.Contains(td1))
                        {
                            newTypedDeps.Add(td1);
                        }
                    }
                }
                list.Clear();
                list.AddRange(newTypedDeps);
            }
        }
        /// <summary>
        /// Add extra nsubj dependencies when collapsing basic dependencies.
        /// 
        /// In the general case, we look for an aux modifier under an xcomp
        /// modifier, and assuming there aren't already associated nsubj
        /// dependencies as daughters of the original xcomp dependency, we
        /// add nsubj dependencies for each nsubj daughter of the aux.
        /// 
        /// There is also a special case for "to" words, in which case we add
        /// a dependency if and only if there is no nsubj associated with the
        /// xcomp and there is no other aux dependency.  This accounts for
        /// sentences such as "he decided not to" with no following verb.
        /// </summary>
        private static void AddExtraNSubj(List<TypedDependency> list)
        {
            var newDeps = new List<TypedDependency>();

            foreach (TypedDependency xcomp in list)
            {
                if (xcomp.Reln != EnglishGrammaticalRelations.XclausalComplement)
                {
                    // we only add extra nsubj dependencies to some xcomp dependencies
                    continue;
                }

                IndexedWord modifier = xcomp.Dep;
                IndexedWord head = xcomp.Gov;

                bool hasSubjectDaughter = false;
                bool hasAux = false;
                var subjects = new List<IndexedWord>();
                var objects = new List<IndexedWord>();
                foreach (TypedDependency dep in list)
                {
                    // already have a subject dependency
                    if ((dep.Reln == EnglishGrammaticalRelations.NominalSubject ||
                         dep.Reln == EnglishGrammaticalRelations.NominalPassiveSubject) &&
                        dep.Gov.Equals(modifier))
                    {
                        hasSubjectDaughter = true;
                        break;
                    }

                    if (dep.Reln == EnglishGrammaticalRelations.AuxModifier && dep.Gov.Equals(modifier))
                    {
                        hasAux = true;
                    }

                    if ((dep.Reln == EnglishGrammaticalRelations.NominalSubject ||
                         dep.Reln == EnglishGrammaticalRelations.NominalPassiveSubject) && dep.Gov.Equals(head))
                    {
                        subjects.Add(dep.Dep);
                    }

                    if (dep.Reln == EnglishGrammaticalRelations.DirectObject && dep.Gov.Equals(head))
                    {
                        objects.Add(dep.Dep);
                    }
                }

                // if we already have an nsubj dependency, no need to add an extra nsubj
                if (hasSubjectDaughter)
                {
                    continue;
                }

                if ((modifier.Value().Equals("to", StringComparison.InvariantCultureIgnoreCase) && hasAux) ||
                    (!modifier.Value().Equals("to", StringComparison.InvariantCultureIgnoreCase) && !hasAux))
                {
                    continue;
                }

                // In general, we find that the objects of the verb are better
                // for extra nsubj than the original nsubj of the verb.  For example,
                // "Many investors wrote asking the SEC to require ..."
                // There is no nsubj of asking, but the dobj, SEC, is the extra nsubj of require.
                // Similarly, "The law tells them when to do so"
                // Instead of nsubj(do, law) we want nsubj(do, them)
                if (objects.Count > 0)
                {
                    foreach (IndexedWord obj in objects)
                    {
                        var newDep = new TypedDependency(EnglishGrammaticalRelations.NominalSubject,
                            modifier, obj);
                        newDeps.Add(newDep);
                    }
                }
                else
                {
                    foreach (IndexedWord subject in subjects)
                    {
                        var newDep = new TypedDependency(EnglishGrammaticalRelations.NominalSubject,
                            modifier, subject);
                        newDeps.Add(newDep);
                    }
                }
            }

            foreach (TypedDependency newDep in newDeps)
            {
                if (!list.Contains(newDep))
                {
                    newDep.Extra = true;
                    list.Add(newDep);
                }
            }
        }
        /// <summary>
        /// Look for ref rules for a given word.  We look through the
        /// children and grandchildren of the rcmod dependency, and if any
        /// children or grandchildren depend on a that/what/which/etc word,
        /// we take the leftmost that/what/which/etc word as the dependent
        /// for the ref TypedDependency.
        /// </summary>
        private static void AddRef(List<TypedDependency> list)
        {
            var newDeps = new List<TypedDependency>();

            foreach (TypedDependency rcmod in list)
            {
                if (rcmod.Reln != EnglishGrammaticalRelations.RelativeClauseModifier)
                {
                    // we only add ref dependencies across relative clauses
                    continue;
                }

                IndexedWord head = rcmod.Gov;
                IndexedWord modifier = rcmod.Dep;

                TypedDependency leftChild = null;
                foreach (TypedDependency child in list)
                {
                    if (child.Gov.Equals(modifier) &&
                        EnglishPatterns.RelativizingWordPattern.IsMatch(child.Dep.Value()) &&
                        (leftChild == null || child.Dep.Index() < leftChild.Dep.Index()))
                    {
                        leftChild = child;
                    }
                }

                // TODO: could be made more efficient
                TypedDependency leftGrandchild = null;
                foreach (TypedDependency child in list)
                {
                    if (!child.Gov.Equals(modifier))
                    {
                        continue;
                    }
                    foreach (TypedDependency grandchild in list)
                    {
                        if (grandchild.Gov.Equals(child.Dep) &&
                            EnglishPatterns.RelativizingWordPattern.IsMatch(grandchild.Dep.Value()) &&
                            (leftGrandchild == null || grandchild.Dep.Index() < leftGrandchild.Dep.Index()))
                        {
                            leftGrandchild = grandchild;
                        }
                    }
                }

                TypedDependency newDep = null;
                if (leftGrandchild != null &&
                    (leftChild == null || leftGrandchild.Dep.Index() < leftChild.Dep.Index()))
                {
                    newDep = new TypedDependency(EnglishGrammaticalRelations.Referent, head, leftGrandchild.Dep);
                }
                else if (leftChild != null)
                {
                    newDep = new TypedDependency(EnglishGrammaticalRelations.Referent, head, leftChild.Dep);
                }
                if (newDep != null)
                {
                    newDeps.Add(newDep);
                }
            }

            foreach (TypedDependency newDep in newDeps)
            {
                if (!list.Contains(newDep))
                {
                    newDep.Extra = true;
                    list.Add(newDep);
                }
            }
        }
        /// <summary>
        /// Work out prep relation name. pc is the dependency whose dep() is the
        /// preposition to do a name for. topPrep may be the same or different.
        /// Among the daughters of its gov is where to look for an auxpass.
        /// </summary>
        private static GrammaticalRelation DeterminePrepRelation(
            Dictionary<IndexedWord, Util.SortedSet<TypedDependency>> map, List<IndexedWord> vmod, TypedDependency pc,
            TypedDependency topPrep, bool pobj)
        {
            // handling the case of an "agent":
            // the governor of a "by" preposition must have an "auxpass" dependency
            // or be the dependent of a "vmod" relation
            // if it is the case, the "agent" variable becomes true
            bool agent = false;
            string preposition = pc.Dep.Value().ToLower();
            if (preposition.Equals("by"))
            {
                // look if we have an auxpass
                Set<TypedDependency> aux_pass_poss = map[topPrep.Gov];
                if (aux_pass_poss != null)
                {
                    foreach (TypedDependency td_pass in aux_pass_poss)
                    {
                        if (td_pass.Reln == EnglishGrammaticalRelations.AuxPassiveModifier)
                        {
                            agent = true;
                        }
                    }
                }
                // look if we have a vmod
                if (vmod.Any() && vmod.Contains(topPrep.Gov))
                {
                    agent = true;
                }
            }

            GrammaticalRelation reln;
            if (agent)
            {
                reln = EnglishGrammaticalRelations.Agent;
            }
            else
            {
                // for prepositions, use the preposition
                // for pobj: we collapse into "prep"; for pcomp: we collapse into "prepc"
                if (pobj)
                {
                    reln = EnglishGrammaticalRelations.GetPrep(preposition);
                }
                else
                {
                    reln = EnglishGrammaticalRelations.GetPrepC(preposition);
                }
            }
            return reln;
        }
        } // end collapsePrepAndPoss()

        private static bool inConjDeps(TypedDependency td, List<Tuple<TypedDependency, TypedDependency, bool>> conjs)
        {
            foreach (Tuple<TypedDependency, TypedDependency, bool> trip in conjs)
            {
                if (td.Equals(trip.Item1))
                {
                    return true;
                }
            }
            return false;
        }
Beispiel #16
0
    public string Tags(string input)
    {
        // Path to models extracted from `stanford-parser-3.6.0-models.jar`
        var jarRoot         = @"";
        var modelsDirectory = jarRoot;

        var lp = LexicalizedParser.loadModel(modelsDirectory + @"\lexparser\englishPCFG.ser.gz");


        // This option shows loading and using an explicit tokenizer
        var sent2            = input;
        var tokenizerFactory = PTBTokenizer.factory(new CoreLabelTokenFactory(), "");
        var sent2Reader      = new java.io.StringReader(sent2);
        var rawWords2        = tokenizerFactory.getTokenizer(sent2Reader).tokenize();

        sent2Reader.close();
        var tree2 = lp.apply(rawWords2);

        // Extract dependencies from lexical tree
        var tlp = new PennTreebankLanguagePack();
        var gsf = tlp.grammaticalStructureFactory();
        var gs  = gsf.newGrammaticalStructure(tree2);
        var tdl = gs.typedDependenciesCCprocessed();


        // Extract collapsed dependencies from parsed tree
        var tp = new TreePrint("penn,typedDependenciesCollapsed");

        UnityEngine.Debug.Log(tdl);
        //tp.printTree(tree2);

        for (int i = 0; i < tdl.size(); i++)
        {
            TypedDependency node = (TypedDependency)tdl.get(i);

            string relation = node.reln().getShortName();

            if (relation.Contains("nsubj"))
            {
                IndexedWord act = node.gov();
                //node.dep().getword()
                action = act.value();

                UnityEngine.Debug.Log("This is the action " + action);

                IndexedWord subject = node.dep();
                subj = subject.value();

                UnityEngine.Debug.Log("This is the subject " + subj);
            }

            if (relation.Contains("dobj"))
            {
                IndexedWord act = node.gov();
                //node.dep().getword()
                action = act.value();
                UnityEngine.Debug.Log("This is the action " + action);

                IndexedWord tar = node.dep();
                target = tar.value();
                UnityEngine.Debug.Log("This is the target " + target);
            }

            if (relation.Contains("nmod"))
            {
                IndexedWord tar_two = node.dep();
                second_target = tar_two.value();
                UnityEngine.Debug.Log("This is the target second " + second_target);
            }
        }

        return(tdl.ToString());
    }