/// <summary>
        /// Returns the deepest shared parent of this node and the specified node.
        /// If the nodes are identical then their parent is returned.
        /// If one node is the parent of the other then the parent node is returned.
        /// </summary>
        /// <param name="node">
        /// The node from which parents are compared to this node's parents.
        /// </param>
        /// <returns>
        /// the deepest shared parent of this node and the specified node.
        /// </returns>
        public virtual Parse GetCommonParent(Parse node)
        {
            if (this == node)
            {
                return(this.Parent);
            }
            Util.HashSet <Parse> parents = new Util.HashSet <Parse>();
            Parse parentParse            = this;

            while (parentParse != null)
            {
                parents.Add(parentParse);
                parentParse = parentParse.Parent;
            }
            while (node != null)
            {
                if (parents.Contains(node))
                {
                    return(node);
                }
                node = node.Parent;
            }
            return(null);
        }
        public static /*<V, E>*/ List <V> GetShortestPath <V, E>(IGraph <V, E> graph, V node1, V node2, bool directionSensitive)
        {
            if (node1.Equals(node2))
            {
                //return Collections.singletonList(node2);
                return(new List <V>()
                {
                    node2
                });
            }

            Set <V> visited        = new Util.HashSet <V>();
            var     previous       = new Dictionary <V, V>();
            var     unsettledNodes = new BinaryHeapPriorityQueue <V>();

            unsettledNodes.Add(node1, 0);

            while (unsettledNodes.Size() > 0)
            {
                var distance = unsettledNodes.GetPriority();
                var u        = unsettledNodes.RemoveFirst();
                visited.Add(u);

                if (u.Equals(node2))
                {
                    break;
                }

                unsettledNodes.Remove(u);

                var candidates = ((directionSensitive) ? graph.GetChildren(u) : new ReadOnlyCollection <V>(graph.GetNeighbors(u)));
                foreach (var candidate in candidates)
                {
                    var alt = distance - 1;
                    // nodes not already present will have a priority of -inf
                    if (alt > unsettledNodes.GetPriority(candidate) && !visited.Contains(candidate))
                    {
                        unsettledNodes.RelaxPriority(candidate, alt);
                        previous[candidate] = u;
                    }
                }
            }

            if (!previous.ContainsKey(node2))
            {
                return(null);
            }
            var path = new List <V>
            {
                node2
            };
            var n = node2;

            while (previous.ContainsKey(n))
            {
                path.Add(previous[n]);
                n = previous[n];
            }
            path.Reverse();
            return(path);
        }
        /// <summary>
        /// Remove duplicate relations: it can happen when collapsing stranded
        /// prepositions. E.g., "What does CPR stand for?" we get dep(stand, what), and
        /// after collapsing we also get prep_for(stand, what).
        /// </summary>
        /// <param name="list">A list of typed dependencies to check through</param>
        private static void RemoveDep(List<TypedDependency> list)
        {
            Set<GrammaticalRelation> prepRels = new Util.HashSet<GrammaticalRelation>(EnglishGrammaticalRelations.GetPreps());
            prepRels.AddAll(EnglishGrammaticalRelations.GetPrepsC());
            foreach (TypedDependency td1 in list)
            {
                if (prepRels.Contains(td1.Reln))
                {
                    // if we have a prep_ relation
                    IndexedWord gov = td1.Gov;
                    IndexedWord dep = td1.Dep;

                    foreach (TypedDependency td2 in list)
                    {
                        if (td2.Reln == GrammaticalRelation.Dependent && td2.Gov.Equals(gov) &&
                            td2.Dep.Equals(dep))
                        {
                            td2.Reln = GrammaticalRelation.Kill;
                        }
                    }
                }
            }

            // now remove typed dependencies with reln "kill"
            /*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);
        }
예제 #4
0
 /// <summary>
 /// Returns the deepest shared parent of this node and the specified node. 
 /// If the nodes are identical then their parent is returned.  
 /// If one node is the parent of the other then the parent node is returned.
 /// </summary>
 /// <param name="node">
 /// The node from which parents are compared to this node's parents.
 /// </param>
 /// <returns>
 /// the deepest shared parent of this node and the specified node.
 /// </returns>
 public virtual Parse GetCommonParent(Parse node)
 {
     if (this == node)
     {
         return this.Parent;
     }
     Util.HashSet<Parse> parents = new Util.HashSet<Parse>();
     Parse parentParse = this;
     while (parentParse != null)
     {
         parents.Add(parentParse);
         parentParse = parentParse.Parent;
     }
     while (node != null)
     {
         if (parents.Contains(node))
         {
             return node;
         }
         node = node.Parent;
     }
     return null;
 }
        private static void TreatCc(List<TypedDependency> list)
        {
            // Construct a map from tree nodes to the set of typed
            // dependencies in which the node appears as dependent.
            var map = new Dictionary<IndexedWord, Set<TypedDependency>>();
            // Construct a map of tree nodes being governor of a subject grammatical
            // relation to that relation
            var subjectMap = new Dictionary<IndexedWord, TypedDependency>();
            // Construct a set of TreeGraphNodes with a passive auxiliary on them
            Set<IndexedWord> withPassiveAuxiliary = new Util.HashSet<IndexedWord>();
            // Construct a map of tree nodes being governor of an object grammatical
            // relation to that relation
            // Map<TreeGraphNode, TypedDependency> objectMap = new
            // HashMap<TreeGraphNode, TypedDependency>();

            var rcmodHeads = new List<IndexedWord>();
            var prepcDep = new List<IndexedWord>();

            foreach (TypedDependency typedDep in list)
            {
                if (!map.ContainsKey(typedDep.Dep))
                {
                    // NB: Here and in other places below, we use a TreeSet (which extends
                    // SortedSet) to guarantee that results are deterministic)
                    map.Add(typedDep.Dep, new TreeSet<TypedDependency>());
                }
                map[typedDep.Dep].Add(typedDep);

                if (typedDep.Reln.Equals(EnglishGrammaticalRelations.AuxPassiveModifier))
                {
                    withPassiveAuxiliary.Add(typedDep.Gov);
                }

                // look for subjects
                if (typedDep.Reln.GetParent() == EnglishGrammaticalRelations.NominalSubject ||
                    typedDep.Reln.GetParent() == EnglishGrammaticalRelations.Subject ||
                    typedDep.Reln.GetParent() == EnglishGrammaticalRelations.ClausalSubject)
                {
                    if (!subjectMap.ContainsKey(typedDep.Gov))
                    {
                        subjectMap.Add(typedDep.Gov, typedDep);
                    }
                }

                // look for objects
                // this map was only required by the code commented out below, so comment
                // it out too
                // if (typedDep.reln() == DIRECT_OBJECT) {
                // if (!objectMap.containsKey(typedDep.gov())) {
                // objectMap.put(typedDep.gov(), typedDep);
                // }
                // }

                // look for rcmod relations
                if (typedDep.Reln == EnglishGrammaticalRelations.RelativeClauseModifier)
                {
                    rcmodHeads.Add(typedDep.Gov);
                }
                // look for prepc relations: put the dependent of such a relation in the
                // list
                // to avoid wrong propagation of dobj
                if (typedDep.Reln.ToString().StartsWith("prepc"))
                {
                    prepcDep.Add(typedDep.Dep);
                }
            }
            
            // create a new list of typed dependencies
            var newTypedDeps = new List<TypedDependency>(list);

            // find typed deps of form conj(gov,dep)
            foreach (TypedDependency td in list)
            {
                if (EnglishGrammaticalRelations.GetConjs().Contains(td.Reln))
                {
                    IndexedWord gov = td.Gov;
                    IndexedWord dep = td.Dep;

                    // look at the dep in the conjunct
                    Set<TypedDependency> govRelations = map[gov];
                    if (govRelations != null)
                    {
                        foreach (TypedDependency td1 in govRelations)
                        {
                            IndexedWord newGov = td1.Gov;
                            // in the case of errors in the basic dependencies, it
                            // is possible to have overlapping newGov & dep
                            if (newGov.Equals(dep))
                            {
                                continue;
                            }
                            GrammaticalRelation newRel = td1.Reln;
                            if (newRel != GrammaticalRelation.Root)
                            {
                                if (rcmodHeads.Contains(gov) && rcmodHeads.Contains(dep))
                                {
                                    // to prevent wrong propagation in the case of long dependencies in relative clauses
                                    if (newRel != EnglishGrammaticalRelations.DirectObject &&
                                        newRel != EnglishGrammaticalRelations.NominalSubject)
                                    {
                                        newTypedDeps.Add(new TypedDependency(newRel, newGov, dep));
                                    }
                                }
                                else
                                {
                                    newTypedDeps.Add(new TypedDependency(newRel, newGov, dep));
                                }
                            }
                        }
                    }

                    // propagate subjects
                    // look at the gov in the conjunct: if it is has a subject relation,
                    // the dep is a verb and the dep doesn't have a subject relation
                    // then we want to add a subject relation for the dep.
                    // (By testing for the dep to be a verb, we are going to miss subject of
                    // copular verbs! but
                    // is it safe to relax this assumption?? i.e., just test for the subject
                    // part)
                    // CDM 2008: I also added in JJ, since participial verbs are often
                    // tagged JJ
                    string tag = dep.Tag();
                    if (subjectMap.ContainsKey(gov) && (PartsOfSpeech.IsVerb(tag) || PartsOfSpeech.IsAdjective(tag)) &&
                        ! subjectMap.ContainsKey(dep))
                    {
                        TypedDependency tdsubj = subjectMap[gov];
                        // check for wrong nsubjpass: if the new verb is VB or VBZ or VBP or JJ, then
                        // add nsubj (if it is tagged correctly, should do this for VBD too, but we don't)
                        GrammaticalRelation relation = tdsubj.Reln;
                        if (relation == EnglishGrammaticalRelations.NominalPassiveSubject)
                        {
                            if (IsDefinitelyActive(tag))
                            {
                                relation = EnglishGrammaticalRelations.NominalSubject;
                            }
                        }
                        else if (relation == EnglishGrammaticalRelations.ClausalPassiveSubject)
                        {
                            if (IsDefinitelyActive(tag))
                            {
                                relation = EnglishGrammaticalRelations.ClausalSubject;
                            }
                        }
                        else if (relation == EnglishGrammaticalRelations.NominalSubject)
                        {
                            if (withPassiveAuxiliary.Contains(dep))
                            {
                                relation = EnglishGrammaticalRelations.NominalPassiveSubject;
                            }
                        }
                        else if (relation == EnglishGrammaticalRelations.ClausalSubject)
                        {
                            if (withPassiveAuxiliary.Contains(dep))
                            {
                                relation = EnglishGrammaticalRelations.ClausalPassiveSubject;
                            }
                        }
                        newTypedDeps.Add(new TypedDependency(relation, dep, tdsubj.Dep));
                    }

                    // propagate objects
                    // cdm july 2010: This bit of code would copy a dobj from the first
                    // clause to a later conjoined clause if it didn't
                    // contain its own dobj or prepc. But this is too aggressive and wrong
                    // if the later clause is intransitive
                    // (including passivized cases) and so I think we have to not have this
                    // done always, and see no good "sometimes" heuristic.
                    // IF WE WERE TO REINSTATE, SHOULD ALSO NOT ADD OBJ IF THERE IS A ccomp
                    // (SBAR).
                    // if (objectMap.containsKey(gov) &&
                    // dep.tag().startsWith("VB") && ! objectMap.containsKey(dep)
                    // && ! prepcDep.contains(gov)) {
                    // TypedDependency tdobj = objectMap.get(gov);
                    // newTypedDeps.add(new TypedDependency(tdobj.reln(), dep,
                    // tdobj.dep()));
                    // }
                }
            }
            list.Clear();
            list.AddRange(newTypedDeps);
        }