public virtual void TestTopologicalSort()
        {
            SemanticGraph gr = SemanticGraph.ValueOf("[ate subj>Bill dobj>[muffins compound>blueberry]]");

            VerifyTopologicalSort(gr);
            IList <IndexedWord> vertices = gr.VertexListSorted();

            gr.AddEdge(vertices[1], vertices[2], UniversalEnglishGrammaticalRelations.DirectObject, 1.0, false);
            VerifyTopologicalSort(gr);
            gr       = SemanticGraph.ValueOf("[ate subj>Bill dobj>[muffins compound>blueberry]]");
            vertices = gr.VertexListSorted();
            gr.AddEdge(vertices[2], vertices[1], UniversalEnglishGrammaticalRelations.DirectObject, 1.0, false);
            VerifyTopologicalSort(gr);
            gr       = SemanticGraph.ValueOf("[ate subj>Bill dobj>[muffins compound>blueberry]]");
            vertices = gr.VertexListSorted();
            gr.AddEdge(vertices[1], vertices[3], UniversalEnglishGrammaticalRelations.DirectObject, 1.0, false);
            VerifyTopologicalSort(gr);
            // now create a graph with a directed loop, which we should not
            // be able to topologically sort
            gr       = SemanticGraph.ValueOf("[ate subj>Bill dobj>[muffins compound>blueberry]]");
            vertices = gr.VertexListSorted();
            gr.AddEdge(vertices[3], vertices[0], UniversalEnglishGrammaticalRelations.DirectObject, 1.0, false);
            try
            {
                VerifyTopologicalSort(gr);
                throw new Exception("Expected to fail");
            }
            catch (InvalidOperationException)
            {
            }
        }
Beispiel #2
0
        /// <summary>Parse a JSON formatted tree into a SemanticGraph.</summary>
        /// <param name="jsonString">
        /// The JSON string tree to parse, e.g:
        /// "[{\"\"dependent\"\": 7, \"\"dep\"\": \"\"root\"\", \"\"governorgloss\"\": \"\"root\"\", \"\"governor\"\": 0, \"\"dependentgloss\"\": \"\"sport\"\"}, {\"\"dependent\"\": 1, \"\"dep\"\": \"\"nsubj\"\", \"\"governorgloss\"\": \"\"sport\"\", \"\"governor\"\": 7, \"\"dependentgloss\"\": \"\"chess\"\"}, {\"\"dependent\"\": 2, \"\"dep\"\": \"\"cop\"\", \"\"governorgloss\"\": \"\"sport\"\", \"\"governor\"\": 7, \"\"dependentgloss\"\": \"\"is\"\"}, {\"\"dependent\"\": 3, \"\"dep\"\": \"\"neg\"\", \"\"governorgloss\"\": \"\"sport\"\", \"\"governor\"\": 7, \"\"dependentgloss\"\": \"\"not\"\"}, {\"\"dependent\"\": 4, \"\"dep\"\": \"\"det\"\", \"\"governorgloss\"\": \"\"sport\"\", \"\"governor\"\": 7, \"\"dependentgloss\"\": \"\"a\"\"}, {\"\"dependent\"\": 5, \"\"dep\"\": \"\"advmod\"\", \"\"governorgloss\"\": \"\"physical\"\", \"\"governor\"\": 6, \"\"dependentgloss\"\": \"\"predominantly\"\"}, {\"\"dependent\"\": 6, \"\"dep\"\": \"\"amod\"\", \"\"governorgloss\"\": \"\"sport\"\", \"\"governor\"\": 7, \"\"dependentgloss\"\": \"\"physical\"\"}, {\"\"dependent\"\": 9, \"\"dep\"\": \"\"advmod\"\", \"\"governorgloss\"\": \"\"sport\"\", \"\"governor\"\": 7, \"\"dependentgloss\"\": \"\"yet\"\"}, {\"\"dependent\"\": 10, \"\"dep\"\": \"\"nsubj\"\", \"\"governorgloss\"\": \"\"shooting\"\", \"\"governor\"\": 12, \"\"dependentgloss\"\": \"\"neither\"\"}, {\"\"dependent\"\": 11, \"\"dep\"\": \"\"cop\"\", \"\"governorgloss\"\": \"\"shooting\"\", \"\"governor\"\": 12, \"\"dependentgloss\"\": \"\"are\"\"}, {\"\"dependent\"\": 12, \"\"dep\"\": \"\"parataxis\"\", \"\"governorgloss\"\": \"\"sport\"\", \"\"governor\"\": 7, \"\"dependentgloss\"\": \"\"shooting\"\"}, {\"\"dependent\"\": 13, \"\"dep\"\": \"\"cc\"\", \"\"governorgloss\"\": \"\"shooting\"\", \"\"governor\"\": 12, \"\"dependentgloss\"\": \"\"and\"\"}, {\"\"dependent\"\": 14, \"\"dep\"\": \"\"parataxis\"\", \"\"governorgloss\"\": \"\"sport\"\", \"\"governor\"\": 7, \"\"dependentgloss\"\": \"\"curling\"\"}, {\"\"dependent\"\": 14, \"\"dep\"\": \"\"conj:and\"\", \"\"governorgloss\"\": \"\"shooting\"\", \"\"governor\"\": 12, \"\"dependentgloss\"\": \"\"curling\"\"}, {\"\"dependent\"\": 16, \"\"dep\"\": \"\"nsubjpass\"\", \"\"governorgloss\"\": \"\"nicknamed\"\", \"\"governor\"\": 23, \"\"dependentgloss\"\": \"\"which\"\"}, {\"\"dependent\"\": 18, \"\"dep\"\": \"\"case\"\", \"\"governorgloss\"\": \"\"fact\"\", \"\"governor\"\": 19, \"\"dependentgloss\"\": \"\"in\"\"}, {\"\"dependent\"\": 19, \"\"dep\"\": \"\"nmod:in\"\", \"\"governorgloss\"\": \"\"nicknamed\"\", \"\"governor\"\": 23, \"\"dependentgloss\"\": \"\"fact\"\"}, {\"\"dependent\"\": 21, \"\"dep\"\": \"\"aux\"\", \"\"governorgloss\"\": \"\"nicknamed\"\", \"\"governor\"\": 23, \"\"dependentgloss\"\": \"\"has\"\"}, {\"\"dependent\"\": 22, \"\"dep\"\": \"\"auxpass\"\", \"\"governorgloss\"\": \"\"nicknamed\"\", \"\"governor\"\": 23, \"\"dependentgloss\"\": \"\"been\"\"}, {\"\"dependent\"\": 23, \"\"dep\"\": \"\"dep\"\", \"\"governorgloss\"\": \"\"shooting\"\", \"\"governor\"\": 12, \"\"dependentgloss\"\": \"\"nicknamed\"\"}, {\"\"dependent\"\": 25, \"\"dep\"\": \"\"dobj\"\", \"\"governorgloss\"\": \"\"nicknamed\"\", \"\"governor\"\": 23, \"\"dependentgloss\"\": \"\"chess\"\"}, {\"\"dependent\"\": 26, \"\"dep\"\": \"\"case\"\", \"\"governorgloss\"\": \"\"ice\"\", \"\"governor\"\": 27, \"\"dependentgloss\"\": \"\"on\"\"}, {\"\"dependent\"\": 27, \"\"dep\"\": \"\"nmod:on\"\", \"\"governorgloss\"\": \"\"chess\"\", \"\"governor\"\": 25, \"\"dependentgloss\"\": \"\"ice\"\"}, {\"\"dependent\"\": 29, \"\"dep\"\": \"\"amod\"\", \"\"governorgloss\"\": \"\"chess\"\", \"\"governor\"\": 25, \"\"dependentgloss\"\": \"\"5\"\"}]");
        /// </param>
        /// <param name="tokens">The tokens of the sentence, to form the backing labels of the tree.</param>
        /// <returns>A semantic graph of the sentence, according to the given tree.</returns>
        public static SemanticGraph ParseJsonTree(string jsonString, IList <CoreLabel> tokens)
        {
            // Escape quoted string parts
            IJsonReader   json  = Javax.Json.Json.CreateReader(new StringReader(jsonString));
            SemanticGraph tree  = new SemanticGraph();
            IJsonArray    array = json.ReadArray();

            if (array == null || array.IsEmpty())
            {
                return(tree);
            }
            IndexedWord[] vertices = new IndexedWord[tokens.Count + 2];
            // Add edges
            for (int i = 0; i < array.Count; i++)
            {
                IJsonObject entry = array.GetJsonObject(i);
                // Parse row
                int dependentIndex = entry.GetInt("dependent");
                if (vertices[dependentIndex] == null)
                {
                    if (dependentIndex > tokens.Count)
                    {
                        // Bizarre mismatch in sizes; the malt parser seems to do this often
                        return(new SemanticGraph());
                    }
                    vertices[dependentIndex] = new IndexedWord(tokens[dependentIndex - 1]);
                }
                IndexedWord dependent     = vertices[dependentIndex];
                int         governorIndex = entry.GetInt("governor");
                if (governorIndex > tokens.Count)
                {
                    // Bizarre mismatch in sizes; the malt parser seems to do this often
                    return(new SemanticGraph());
                }
                if (vertices[governorIndex] == null && governorIndex > 0)
                {
                    vertices[governorIndex] = new IndexedWord(tokens[governorIndex - 1]);
                }
                IndexedWord governor = vertices[governorIndex];
                string      relation = entry.GetString("dep");
                // Process row
                if (governorIndex == 0)
                {
                    tree.AddRoot(dependent);
                }
                else
                {
                    tree.AddVertex(dependent);
                    if (!tree.ContainsVertex(governor))
                    {
                        tree.AddVertex(governor);
                    }
                    if (!"ref".Equals(relation))
                    {
                        tree.AddEdge(governor, dependent, GrammaticalRelation.ValueOf(Language.English, relation), double.NegativeInfinity, false);
                    }
                }
            }
            return(tree);
        }
Beispiel #3
0
 /// <summary>Create a copy of the passed parse tree, canonicalizing pronominal nodes with their canonical mention.</summary>
 /// <remarks>
 /// Create a copy of the passed parse tree, canonicalizing pronominal nodes with their canonical mention.
 /// Canonical mentions are tied together with the <i>compound</i> dependency arc; otherwise, the structure of
 /// the tree remains unchanged.
 /// </remarks>
 /// <param name="parse">The original dependency parse of the sentence.</param>
 /// <param name="canonicalMentionMap">The map from tokens to their canonical mentions.</param>
 /// <returns>A <b>copy</b> of the passed parse tree, with pronouns replaces with their canonical mention.</returns>
 private static SemanticGraph CanonicalizeCoref(SemanticGraph parse, IDictionary <CoreLabel, IList <CoreLabel> > canonicalMentionMap)
 {
     parse = new SemanticGraph(parse);
     foreach (IndexedWord node in new HashSet <IndexedWord>(parse.VertexSet()))
     {
         // copy the vertex set to prevent ConcurrentModificationExceptions
         if (node.Tag() != null && node.Tag().StartsWith("PRP"))
         {
             IList <CoreLabel> canonicalMention = canonicalMentionMap[node.BackingLabel()];
             if (canonicalMention != null)
             {
                 // Case: this node is a preposition with a valid antecedent.
                 // 1. Save the attaching edges
                 IList <SemanticGraphEdge> incomingEdges = parse.IncomingEdgeList(node);
                 IList <SemanticGraphEdge> outgoingEdges = parse.OutgoingEdgeList(node);
                 // 2. Remove the node
                 parse.RemoveVertex(node);
                 // 3. Add the new head word
                 IndexedWord headWord = new IndexedWord(canonicalMention[canonicalMention.Count - 1]);
                 headWord.SetPseudoPosition(node.PseudoPosition());
                 parse.AddVertex(headWord);
                 foreach (SemanticGraphEdge edge in incomingEdges)
                 {
                     parse.AddEdge(edge.GetGovernor(), headWord, edge.GetRelation(), edge.GetWeight(), edge.IsExtra());
                 }
                 foreach (SemanticGraphEdge edge_1 in outgoingEdges)
                 {
                     parse.AddEdge(headWord, edge_1.GetDependent(), edge_1.GetRelation(), edge_1.GetWeight(), edge_1.IsExtra());
                 }
                 // 4. Add other words
                 double pseudoPosition = headWord.PseudoPosition() - 1e-3;
                 for (int i = canonicalMention.Count - 2; i >= 0; --i)
                 {
                     // Create the node
                     IndexedWord dependent = new IndexedWord(canonicalMention[i]);
                     // Set its pseudo position appropriately
                     dependent.SetPseudoPosition(pseudoPosition);
                     pseudoPosition -= 1e-3;
                     // Add the node to the graph
                     parse.AddVertex(dependent);
                     parse.AddEdge(headWord, dependent, UniversalEnglishGrammaticalRelations.CompoundModifier, 1.0, false);
                 }
             }
         }
     }
     return(parse);
 }
Beispiel #4
0
        /// <summary>Parse a CoNLL formatted tree into a SemanticGraph.</summary>
        /// <param name="conll">The CoNLL tree to parse.</param>
        /// <param name="tokens">The tokens of the sentence, to form the backing labels of the tree.</param>
        /// <returns>A semantic graph of the sentence, according to the given tree.</returns>
        public static SemanticGraph ParseTree(string conll, IList <CoreLabel> tokens)
        {
            SemanticGraph tree = new SemanticGraph();

            if (conll == null || conll.IsEmpty())
            {
                return(tree);
            }
            string[]      treeLines = newline.Split(conll);
            IndexedWord[] vertices  = new IndexedWord[tokens.Count + 2];
            // Add edges
            foreach (string line in treeLines)
            {
                // Parse row
                string[] fields         = tab.Split(line);
                int      dependentIndex = System.Convert.ToInt32(fields[0]);
                if (vertices[dependentIndex] == null)
                {
                    if (dependentIndex > tokens.Count)
                    {
                        // Bizarre mismatch in sizes; the malt parser seems to do this often
                        return(new SemanticGraph());
                    }
                    vertices[dependentIndex] = new IndexedWord(tokens[dependentIndex - 1]);
                }
                IndexedWord dependent     = vertices[dependentIndex];
                int         governorIndex = System.Convert.ToInt32(fields[1]);
                if (governorIndex > tokens.Count)
                {
                    // Bizarre mismatch in sizes; the malt parser seems to do this often
                    return(new SemanticGraph());
                }
                if (vertices[governorIndex] == null && governorIndex > 0)
                {
                    vertices[governorIndex] = new IndexedWord(tokens[governorIndex - 1]);
                }
                IndexedWord governor = vertices[governorIndex];
                string      relation = fields[2];
                // Process row
                if (governorIndex == 0)
                {
                    tree.AddRoot(dependent);
                }
                else
                {
                    tree.AddVertex(dependent);
                    if (!tree.ContainsVertex(governor))
                    {
                        tree.AddVertex(governor);
                    }
                    if (!"ref".Equals(relation))
                    {
                        tree.AddEdge(governor, dependent, GrammaticalRelation.ValueOf(Language.English, relation), double.NegativeInfinity, false);
                    }
                }
            }
            return(tree);
        }
Beispiel #5
0
        /// <summary>Parse a CoNLL formatted tree into a SemanticGraph object (along with a list of tokens).</summary>
        /// <param name="conll">The CoNLL formatted tree.</param>
        /// <returns>
        /// A pair of a SemanticGraph and a token list, corresponding to the parse of the sentence
        /// and to tokens in the sentence.
        /// </returns>
        protected internal virtual Pair <SemanticGraph, IList <CoreLabel> > MkTree(string conll)
        {
            IList <CoreLabel> sentence = new List <CoreLabel>();
            SemanticGraph     tree     = new SemanticGraph();

            foreach (string line in conll.Split("\n"))
            {
                if (line.Trim().Equals(string.Empty))
                {
                    continue;
                }
                string[]  fields = line.Trim().Split("\\s+");
                int       index  = System.Convert.ToInt32(fields[0]);
                string    word   = fields[1];
                CoreLabel label  = IETestUtils.MkWord(word, index);
                sentence.Add(label);
                if (fields[2].Equals("0"))
                {
                    tree.AddRoot(new IndexedWord(label));
                }
                else
                {
                    tree.AddVertex(new IndexedWord(label));
                }
                if (fields.Length > 4)
                {
                    label.SetTag(fields[4]);
                }
                if (fields.Length > 5)
                {
                    label.SetNER(fields[5]);
                }
                if (fields.Length > 6)
                {
                    label.SetLemma(fields[6]);
                }
            }
            int i = 0;

            foreach (string line_1 in conll.Split("\n"))
            {
                if (line_1.Trim().Equals(string.Empty))
                {
                    continue;
                }
                string[] fields = line_1.Trim().Split("\\s+");
                int      parent = System.Convert.ToInt32(fields[2]);
                string   reln   = fields[3];
                if (parent > 0)
                {
                    tree.AddEdge(new IndexedWord(sentence[parent - 1]), new IndexedWord(sentence[i]), new GrammaticalRelation(Language.UniversalEnglish, reln, null, null), 1.0, false);
                }
                i += 1;
            }
            return(Pair.MakePair(tree, sentence));
        }
Beispiel #6
0
        /// <summary>TODO: figure out how to specify where in the sentence this node goes.</summary>
        /// <remarks>
        /// TODO: figure out how to specify where in the sentence this node goes.
        /// TODO: determine if we should be copying an IndexedWord, or working just with a FeatureLabel.
        /// TODO: bombproof if this gov, dep, and reln already exist.
        /// </remarks>
        public override void Evaluate(SemanticGraph sg, SemgrexMatcher sm)
        {
            IndexedWord govNode  = sm.GetNode(govNodeName);
            IndexedWord newNode  = new IndexedWord(newNodePrototype);
            int         newIndex = SemanticGraphUtils.LeftMostChildVertice(govNode, sg).Index();

            // cheap En-specific hack for placing copula (beginning of governing phrase)
            newNode.SetDocID(govNode.DocID());
            newNode.SetIndex(newIndex);
            newNode.SetSentIndex(govNode.SentIndex());
            sg.AddVertex(newNode);
            sg.AddEdge(govNode, newNode, relation, weight, false);
        }
        /// <summary>This creates a new graph based off the given, but uses the existing nodes objects.</summary>
        public static SemanticGraph DuplicateKeepNodes(SemanticGraph sg)
        {
            SemanticGraph retSg = new SemanticGraph();

            foreach (IndexedWord node in sg.VertexSet())
            {
                retSg.AddVertex(node);
            }
            retSg.SetRoots(sg.GetRoots());
            foreach (SemanticGraphEdge edge in sg.EdgeIterable())
            {
                retSg.AddEdge(edge.GetGovernor(), edge.GetDependent(), edge.GetRelation(), edge.GetWeight(), edge.IsExtra());
            }
            return(retSg);
        }
        /// <summary>Given a list of edges, attempts to create and return a rooted SemanticGraph.</summary>
        /// <remarks>
        /// Given a list of edges, attempts to create and return a rooted SemanticGraph.
        /// TODO: throw Exceptions, or flag warnings on conditions for concern (no root, etc)
        /// </remarks>
        public static SemanticGraph MakeFromEdges(IEnumerable <SemanticGraphEdge> edges)
        {
            // Identify the root(s) of this graph
            SemanticGraph             sg       = new SemanticGraph();
            ICollection <IndexedWord> vertices = GetVerticesFromEdgeSet(edges);

            foreach (IndexedWord vertex in vertices)
            {
                sg.AddVertex(vertex);
            }
            foreach (SemanticGraphEdge edge in edges)
            {
                sg.AddEdge(edge.GetSource(), edge.GetTarget(), edge.GetRelation(), edge.GetWeight(), edge.IsExtra());
            }
            sg.ResetRoots();
            return(sg);
        }
        /// <summary>
        /// Given a set of vertices, and the source graph they are drawn from, create a path composed
        /// of the minimum paths between the vertices.
        /// </summary>
        /// <remarks>
        /// Given a set of vertices, and the source graph they are drawn from, create a path composed
        /// of the minimum paths between the vertices.  i.e. this is a simple brain-dead attempt at getting
        /// something approximating a minimum spanning graph.
        /// NOTE: the hope is the vertices will already be contiguous, but facilities are added just in case for
        /// adding additional nodes.
        /// </remarks>
        public static SemanticGraph MakeFromVertices(SemanticGraph sg, ICollection <IndexedWord> nodes)
        {
            IList <SemanticGraphEdge> edgesToAdd = new List <SemanticGraphEdge>();
            IList <IndexedWord>       nodesToAdd = new List <IndexedWord>(nodes);

            foreach (IndexedWord nodeA in nodes)
            {
                foreach (IndexedWord nodeB in nodes)
                {
                    if (nodeA != nodeB)
                    {
                        IList <SemanticGraphEdge> edges = sg.GetShortestDirectedPathEdges(nodeA, nodeB);
                        if (edges != null)
                        {
                            Sharpen.Collections.AddAll(edgesToAdd, edges);
                            foreach (SemanticGraphEdge edge in edges)
                            {
                                IndexedWord gov = edge.GetGovernor();
                                IndexedWord dep = edge.GetDependent();
                                if (gov != null && !nodesToAdd.Contains(gov))
                                {
                                    nodesToAdd.Add(gov);
                                }
                                if (dep != null && !nodesToAdd.Contains(dep))
                                {
                                    nodesToAdd.Add(dep);
                                }
                            }
                        }
                    }
                }
            }
            SemanticGraph retSg = new SemanticGraph();

            foreach (IndexedWord node in nodesToAdd)
            {
                retSg.AddVertex(node);
            }
            foreach (SemanticGraphEdge edge_1 in edgesToAdd)
            {
                retSg.AddEdge(edge_1.GetGovernor(), edge_1.GetDependent(), edge_1.GetRelation(), edge_1.GetWeight(), edge_1.IsExtra());
            }
            retSg.ResetRoots();
            return(retSg);
        }
Beispiel #10
0
        public override void Evaluate(SemanticGraph sg, SemgrexMatcher sm)
        {
            IndexedWord rootNode = this.GetNamedNode(rootName, sm);
            ICollection <IndexedWord> subgraphNodeSet = sg.GetSubgraphVertices(rootNode);

            if (!sg.IsDag(rootNode))
            {
                /* Check if there is a cycle going back to the root. */
                foreach (IndexedWord child in sg.GetChildren(rootNode))
                {
                    ICollection <IndexedWord> reachableSet = sg.GetSubgraphVertices(child);
                    if (reachableSet.Contains(rootNode))
                    {
                        throw new ArgumentException("Subtree cannot contain cycle leading back to root node!");
                    }
                }
            }
            IList <IndexedWord> sortedSubgraphNodes = Generics.NewArrayList(subgraphNodeSet);

            sortedSubgraphNodes.Sort();
            IndexedWord newNode = new IndexedWord(rootNode.DocID(), rootNode.SentIndex(), rootNode.Index());

            /* Copy all attributes from rootNode. */
            foreach (Type key in newNode.BackingLabel().KeySet())
            {
                newNode.Set(key, rootNode.Get(key));
            }
            newNode.SetValue(StringUtils.Join(sortedSubgraphNodes.Stream().Map(null), " "));
            newNode.SetWord(StringUtils.Join(sortedSubgraphNodes.Stream().Map(null), " "));
            newNode.SetLemma(StringUtils.Join(sortedSubgraphNodes.Stream().Map(null), " "));
            if (sg.GetRoots().Contains(rootNode))
            {
                sg.GetRoots().Remove(rootNode);
                sg.AddRoot(rootNode);
            }
            foreach (SemanticGraphEdge edge in sg.IncomingEdgeIterable(rootNode))
            {
                sg.AddEdge(edge.GetGovernor(), newNode, edge.GetRelation(), edge.GetWeight(), edge.IsExtra());
            }
            foreach (IndexedWord node in sortedSubgraphNodes)
            {
                sg.RemoveVertex(node);
            }
        }
        /// <summary>
        /// Given a list of graphs, constructs a new graph combined from the
        /// collection of graphs.
        /// </summary>
        /// <remarks>
        /// Given a list of graphs, constructs a new graph combined from the
        /// collection of graphs.  Original vertices are used, edges are
        /// copied.  Graphs are ordered by the sentence index and index of
        /// the original vertices.  Intent is to create a "mega graph"
        /// similar to the graphs used in the RTE problem.
        /// <br />
        /// This method only works if the indexed words have different
        /// sentence ids, as otherwise the maps used will confuse several of
        /// the IndexedWords.
        /// </remarks>
        public static SemanticGraph MakeFromGraphs(ICollection <SemanticGraph> sgList)
        {
            SemanticGraph             sg       = new SemanticGraph();
            ICollection <IndexedWord> newRoots = Generics.NewHashSet();

            foreach (SemanticGraph currSg in sgList)
            {
                Sharpen.Collections.AddAll(newRoots, currSg.GetRoots());
                foreach (IndexedWord currVertex in currSg.VertexSet())
                {
                    sg.AddVertex(currVertex);
                }
                foreach (SemanticGraphEdge currEdge in currSg.EdgeIterable())
                {
                    sg.AddEdge(currEdge.GetGovernor(), currEdge.GetDependent(), currEdge.GetRelation(), currEdge.GetWeight(), currEdge.IsExtra());
                }
            }
            sg.SetRoots(newRoots);
            return(sg);
        }
Beispiel #12
0
        public override void Evaluate(SemanticGraph sg, SemgrexMatcher sm)
        {
            IndexedWord       govNode      = GetNamedNode(govName, sm);
            IndexedWord       depNode      = GetNamedNode(depName, sm);
            SemanticGraphEdge existingEdge = sg.GetEdge(govNode, depNode, relation);

            if (existingEdge == null)
            {
                // When adding the edge, check to see if the gov/dep nodes are presently in the graph.
                //
                if (!sg.ContainsVertex(govNode))
                {
                    sg.AddVertex(govNode);
                }
                if (!sg.ContainsVertex(depNode))
                {
                    sg.AddVertex(depNode);
                }
                sg.AddEdge(govNode, depNode, relation, weight, false);
            }
        }
        /// <summary>
        /// Like makeFromGraphs, but it makes a deep copy of the graphs and
        /// renumbers the index words.
        /// </summary>
        /// <remarks>
        /// Like makeFromGraphs, but it makes a deep copy of the graphs and
        /// renumbers the index words.
        /// <br />
        /// <paramref name="lengths"/>
        /// must be a vector containing the number of
        /// tokens in each sentence.  This is used to reindex the tokens.
        /// </remarks>
        public static SemanticGraph DeepCopyFromGraphs(IList <SemanticGraph> graphs, IList <int> lengths)
        {
            SemanticGraph newGraph = new SemanticGraph();
            IDictionary <int, IndexedWord> newWords = Generics.NewHashMap();
            IList <IndexedWord>            newRoots = new List <IndexedWord>();
            int vertexOffset = 0;

            for (int i = 0; i < graphs.Count; ++i)
            {
                SemanticGraph graph = graphs[i];
                foreach (IndexedWord vertex in graph.VertexSet())
                {
                    IndexedWord newVertex = new IndexedWord(vertex);
                    newVertex.SetIndex(vertex.Index() + vertexOffset);
                    newGraph.AddVertex(newVertex);
                    newWords[newVertex.Index()] = newVertex;
                }
                foreach (SemanticGraphEdge edge in graph.EdgeIterable())
                {
                    IndexedWord gov = newWords[edge.GetGovernor().Index() + vertexOffset];
                    IndexedWord dep = newWords[edge.GetDependent().Index() + vertexOffset];
                    if (gov == null || dep == null)
                    {
                        throw new AssertionError("Counting problem (or broken edge)");
                    }
                    newGraph.AddEdge(gov, dep, edge.GetRelation(), edge.GetWeight(), edge.IsExtra());
                }
                foreach (IndexedWord root in graph.GetRoots())
                {
                    newRoots.Add(newWords[root.Index() + vertexOffset]);
                }
                vertexOffset += lengths[i];
            }
            newGraph.SetRoots(newRoots);
            return(newGraph);
        }
Beispiel #14
0
        // TODO: implement referencing regexes
        public static SemanticGraph MakeComplicatedGraph()
        {
            SemanticGraph graph = new SemanticGraph();

            string[]      words = new string[] { "A", "B", "C", "D", "E", "F", "G", "H", "I", "J" };
            IndexedWord[] nodes = new IndexedWord[words.Length];
            for (int i = 0; i < words.Length; ++i)
            {
                IndexedWord word = new IndexedWord("test", 1, i + 1);
                word.SetWord(words[i]);
                word.SetValue(words[i]);
                nodes[i] = word;
                graph.AddVertex(word);
            }
            graph.SetRoot(nodes[0]);
            // this graph isn't supposed to make sense
            graph.AddEdge(nodes[0], nodes[1], EnglishGrammaticalRelations.Modifier, 1.0, false);
            graph.AddEdge(nodes[0], nodes[2], EnglishGrammaticalRelations.DirectObject, 1.0, false);
            graph.AddEdge(nodes[0], nodes[3], EnglishGrammaticalRelations.IndirectObject, 1.0, false);
            graph.AddEdge(nodes[1], nodes[4], EnglishGrammaticalRelations.Marker, 1.0, false);
            graph.AddEdge(nodes[2], nodes[4], EnglishGrammaticalRelations.Expletive, 1.0, false);
            graph.AddEdge(nodes[3], nodes[4], EnglishGrammaticalRelations.AdjectivalComplement, 1.0, false);
            graph.AddEdge(nodes[4], nodes[5], EnglishGrammaticalRelations.AdjectivalModifier, 1.0, false);
            graph.AddEdge(nodes[4], nodes[6], EnglishGrammaticalRelations.AdverbialModifier, 1.0, false);
            graph.AddEdge(nodes[4], nodes[8], EnglishGrammaticalRelations.Modifier, 1.0, false);
            graph.AddEdge(nodes[5], nodes[7], EnglishGrammaticalRelations.PossessionModifier, 1.0, false);
            graph.AddEdge(nodes[6], nodes[7], EnglishGrammaticalRelations.PossessiveModifier, 1.0, false);
            graph.AddEdge(nodes[7], nodes[8], EnglishGrammaticalRelations.Agent, 1.0, false);
            graph.AddEdge(nodes[8], nodes[9], EnglishGrammaticalRelations.Determiner, 1.0, false);
            return(graph);
        }
Beispiel #15
0
        protected internal virtual ICollection <string> Clauses(string conll)
        {
            IList <CoreLabel> sentence = new List <CoreLabel>();
            SemanticGraph     tree     = new SemanticGraph();

            foreach (string line in conll.Split("\n"))
            {
                if (line.Trim().Equals(string.Empty))
                {
                    continue;
                }
                string[]  fields = line.Trim().Split("\\s+");
                int       index  = System.Convert.ToInt32(fields[0]);
                string    word   = fields[1];
                CoreLabel label  = MkWord(word, index);
                sentence.Add(label);
                if (fields[2].Equals("0"))
                {
                    tree.AddRoot(new IndexedWord(label));
                }
                else
                {
                    tree.AddVertex(new IndexedWord(label));
                }
                if (fields.Length > 4)
                {
                    label.SetTag(fields[4]);
                }
                if (fields.Length > 5)
                {
                    label.SetNER(fields[5]);
                }
                if (fields.Length > 6)
                {
                    label.SetLemma(fields[6]);
                }
            }
            int i = 0;

            foreach (string line_1 in conll.Split("\n"))
            {
                if (line_1.Trim().Equals(string.Empty))
                {
                    continue;
                }
                string[] fields = line_1.Trim().Split("\\s+");
                int      parent = System.Convert.ToInt32(fields[2]);
                string   reln   = fields[3];
                if (parent > 0)
                {
                    tree.AddEdge(new IndexedWord(sentence[parent - 1]), new IndexedWord(sentence[i]), new GrammaticalRelation(Language.English, reln, null, null), 1.0, false);
                }
                i += 1;
            }
            // Run extractor
            ClauseSplitterSearchProblem problem = new ClauseSplitterSearchProblem(tree, true);
            ICollection <string>        clauses = new HashSet <string>();

            problem.Search(null, new LinearClassifier <ClauseSplitter.ClauseClassifierLabel, string>(new ClassicCounter <Pair <string, ClauseSplitter.ClauseClassifierLabel> >()), ClauseSplitterSearchProblem.HardSplits, null, 100000);
            return(clauses);
        }
Beispiel #16
0
        /// <summary>The search algorithm, starting with a full sentence and iteratively shortening it to its entailed sentences.</summary>
        /// <returns>A list of search results, corresponding to shortenings of the sentence.</returns>
        private IList <ForwardEntailerSearchProblem.SearchResult> SearchImplementation()
        {
            // Pre-process the tree
            SemanticGraph parseTree = new SemanticGraph(this.parseTree);

            System.Diagnostics.Debug.Assert(Edu.Stanford.Nlp.Naturalli.Util.IsTree(parseTree));
            // (remove common determiners)
            IList <string> determinerRemovals = new List <string>();

            parseTree.GetLeafVertices().Stream().Filter(null).ForEach(null);
            // (cut conj_and nodes)
            ICollection <SemanticGraphEdge> andsToAdd = new HashSet <SemanticGraphEdge>();

            foreach (IndexedWord vertex in parseTree.VertexSet())
            {
                if (parseTree.InDegree(vertex) > 1)
                {
                    SemanticGraphEdge conjAnd = null;
                    foreach (SemanticGraphEdge edge in parseTree.IncomingEdgeIterable(vertex))
                    {
                        if ("conj:and".Equals(edge.GetRelation().ToString()))
                        {
                            conjAnd = edge;
                        }
                    }
                    if (conjAnd != null)
                    {
                        parseTree.RemoveEdge(conjAnd);
                        System.Diagnostics.Debug.Assert(Edu.Stanford.Nlp.Naturalli.Util.IsTree(parseTree));
                        andsToAdd.Add(conjAnd);
                    }
                }
            }
            // Clean the tree
            Edu.Stanford.Nlp.Naturalli.Util.CleanTree(parseTree);
            System.Diagnostics.Debug.Assert(Edu.Stanford.Nlp.Naturalli.Util.IsTree(parseTree));
            // Find the subject / object split
            // This takes max O(n^2) time, expected O(n*log(n)) time.
            // Optimal is O(n), but I'm too lazy to implement it.
            BitSet isSubject = new BitSet(256);

            foreach (IndexedWord vertex_1 in parseTree.VertexSet())
            {
                // Search up the tree for a subj node; if found, mark that vertex as a subject.
                IEnumerator <SemanticGraphEdge> incomingEdges = parseTree.IncomingEdgeIterator(vertex_1);
                SemanticGraphEdge edge = null;
                if (incomingEdges.MoveNext())
                {
                    edge = incomingEdges.Current;
                }
                int numIters = 0;
                while (edge != null)
                {
                    if (edge.GetRelation().ToString().EndsWith("subj"))
                    {
                        System.Diagnostics.Debug.Assert(vertex_1.Index() > 0);
                        isSubject.Set(vertex_1.Index() - 1);
                        break;
                    }
                    incomingEdges = parseTree.IncomingEdgeIterator(edge.GetGovernor());
                    if (incomingEdges.MoveNext())
                    {
                        edge = incomingEdges.Current;
                    }
                    else
                    {
                        edge = null;
                    }
                    numIters += 1;
                    if (numIters > 100)
                    {
                        //          log.error("tree has apparent depth > 100");
                        return(Java.Util.Collections.EmptyList);
                    }
                }
            }
            // Outputs
            IList <ForwardEntailerSearchProblem.SearchResult> results = new List <ForwardEntailerSearchProblem.SearchResult>();

            if (!determinerRemovals.IsEmpty())
            {
                if (andsToAdd.IsEmpty())
                {
                    double score = Math.Pow(weights.DeletionProbability("det"), (double)determinerRemovals.Count);
                    System.Diagnostics.Debug.Assert(!double.IsNaN(score));
                    System.Diagnostics.Debug.Assert(!double.IsInfinite(score));
                    results.Add(new ForwardEntailerSearchProblem.SearchResult(parseTree, determinerRemovals, score));
                }
                else
                {
                    SemanticGraph treeWithAnds = new SemanticGraph(parseTree);
                    System.Diagnostics.Debug.Assert(Edu.Stanford.Nlp.Naturalli.Util.IsTree(treeWithAnds));
                    foreach (SemanticGraphEdge and in andsToAdd)
                    {
                        treeWithAnds.AddEdge(and.GetGovernor(), and.GetDependent(), and.GetRelation(), double.NegativeInfinity, false);
                    }
                    System.Diagnostics.Debug.Assert(Edu.Stanford.Nlp.Naturalli.Util.IsTree(treeWithAnds));
                    results.Add(new ForwardEntailerSearchProblem.SearchResult(treeWithAnds, determinerRemovals, Math.Pow(weights.DeletionProbability("det"), (double)determinerRemovals.Count)));
                }
            }
            // Initialize the search
            System.Diagnostics.Debug.Assert(Edu.Stanford.Nlp.Naturalli.Util.IsTree(parseTree));
            IList <IndexedWord> topologicalVertices;

            try
            {
                topologicalVertices = parseTree.TopologicalSort();
            }
            catch (InvalidOperationException)
            {
                //      log.info("Could not topologically sort the vertices! Using left-to-right traversal.");
                topologicalVertices = parseTree.VertexListSorted();
            }
            if (topologicalVertices.IsEmpty())
            {
                return(results);
            }
            Stack <ForwardEntailerSearchProblem.SearchState> fringe = new Stack <ForwardEntailerSearchProblem.SearchState>();

            fringe.Push(new ForwardEntailerSearchProblem.SearchState(new BitSet(256), 0, parseTree, null, null, 1.0));
            // Start the search
            int numTicks = 0;

            while (!fringe.IsEmpty())
            {
                // Overhead with popping a node.
                if (numTicks >= maxTicks)
                {
                    return(results);
                }
                numTicks += 1;
                if (results.Count >= maxResults)
                {
                    return(results);
                }
                ForwardEntailerSearchProblem.SearchState state = fringe.Pop();
                System.Diagnostics.Debug.Assert(state.score > 0.0);
                IndexedWord currentWord = topologicalVertices[state.currentIndex];
                // Push the case where we don't delete
                int nextIndex = state.currentIndex + 1;
                int numIters  = 0;
                while (nextIndex < topologicalVertices.Count)
                {
                    IndexedWord nextWord = topologicalVertices[nextIndex];
                    System.Diagnostics.Debug.Assert(nextWord.Index() > 0);
                    if (!state.deletionMask.Get(nextWord.Index() - 1))
                    {
                        fringe.Push(new ForwardEntailerSearchProblem.SearchState(state.deletionMask, nextIndex, state.tree, null, state, state.score));
                        break;
                    }
                    else
                    {
                        nextIndex += 1;
                    }
                    numIters += 1;
                    if (numIters > 10000)
                    {
                        //          log.error("logic error (apparent infinite loop); returning");
                        return(results);
                    }
                }
                // Check if we can delete this subtree
                bool canDelete = !state.tree.GetFirstRoot().Equals(currentWord);
                foreach (SemanticGraphEdge edge in state.tree.IncomingEdgeIterable(currentWord))
                {
                    if ("CD".Equals(edge.GetGovernor().Tag()))
                    {
                        canDelete = false;
                    }
                    else
                    {
                        // Get token information
                        CoreLabel            token = edge.GetDependent().BackingLabel();
                        OperatorSpec         @operator;
                        NaturalLogicRelation lexicalRelation;
                        Polarity             tokenPolarity = token.Get(typeof(NaturalLogicAnnotations.PolarityAnnotation));
                        if (tokenPolarity == null)
                        {
                            tokenPolarity = Polarity.Default;
                        }
                        // Get the relation for this deletion
                        if ((@operator = token.Get(typeof(NaturalLogicAnnotations.OperatorAnnotation))) != null)
                        {
                            lexicalRelation = @operator.instance.deleteRelation;
                        }
                        else
                        {
                            System.Diagnostics.Debug.Assert(edge.GetDependent().Index() > 0);
                            lexicalRelation = NaturalLogicRelation.ForDependencyDeletion(edge.GetRelation().ToString(), isSubject.Get(edge.GetDependent().Index() - 1));
                        }
                        NaturalLogicRelation projectedRelation = tokenPolarity.ProjectLexicalRelation(lexicalRelation);
                        // Make sure this is a valid entailment
                        if (!projectedRelation.ApplyToTruthValue(truthOfPremise).IsTrue())
                        {
                            canDelete = false;
                        }
                    }
                }
                if (canDelete)
                {
                    // Register the deletion
                    Lazy <Pair <SemanticGraph, BitSet> > treeWithDeletionsAndNewMask = Lazy.Of(null);
                    // Compute the score of the sentence
                    double newScore = state.score;
                    foreach (SemanticGraphEdge edge_1 in state.tree.IncomingEdgeIterable(currentWord))
                    {
                        double multiplier = weights.DeletionProbability(edge_1, state.tree.OutgoingEdgeIterable(edge_1.GetGovernor()));
                        System.Diagnostics.Debug.Assert(!double.IsNaN(multiplier));
                        System.Diagnostics.Debug.Assert(!double.IsInfinite(multiplier));
                        newScore *= multiplier;
                    }
                    // Register the result
                    if (newScore > 0.0)
                    {
                        SemanticGraph resultTree = new SemanticGraph(treeWithDeletionsAndNewMask.Get().first);
                        andsToAdd.Stream().Filter(null).ForEach(null);
                        results.Add(new ForwardEntailerSearchProblem.SearchResult(resultTree, AggregateDeletedEdges(state, state.tree.IncomingEdgeIterable(currentWord), determinerRemovals), newScore));
                        // Push the state with this subtree deleted
                        nextIndex = state.currentIndex + 1;
                        numIters  = 0;
                        while (nextIndex < topologicalVertices.Count)
                        {
                            IndexedWord   nextWord          = topologicalVertices[nextIndex];
                            BitSet        newMask           = treeWithDeletionsAndNewMask.Get().second;
                            SemanticGraph treeWithDeletions = treeWithDeletionsAndNewMask.Get().first;
                            if (!newMask.Get(nextWord.Index() - 1))
                            {
                                System.Diagnostics.Debug.Assert(treeWithDeletions.ContainsVertex(topologicalVertices[nextIndex]));
                                fringe.Push(new ForwardEntailerSearchProblem.SearchState(newMask, nextIndex, treeWithDeletions, null, state, newScore));
                                break;
                            }
                            else
                            {
                                nextIndex += 1;
                            }
                            numIters += 1;
                            if (numIters > 10000)
                            {
                                //              log.error("logic error (apparent infinite loop); returning");
                                return(results);
                            }
                        }
                    }
                }
            }
            // Return
            return(results);
        }
Beispiel #17
0
            public virtual SemanticGraph ConvertIntermediateGraph(IList <CoreLabel> sentence)
            {
                SemanticGraph graph = new SemanticGraph();
                // First construct the actual nodes; keep them indexed by their index and copy count.
                // Sentences such as "I went over the river and through the woods" have
                // two copies for "went" in the collapsed dependencies.
                TwoDimensionalMap <int, int, IndexedWord> nodeMap = TwoDimensionalMap.HashMap();

                foreach (AnnotationSerializer.IntermediateNode @in in nodes)
                {
                    CoreLabel token = sentence[@in.index - 1];
                    // index starts at 1!
                    IndexedWord word;
                    if (@in.copyAnnotation > 0)
                    {
                        // TODO: if we make a copy wrapper CoreLabel, use it here instead
                        word = new IndexedWord(new CoreLabel(token));
                        word.SetCopyCount(@in.copyAnnotation);
                    }
                    else
                    {
                        word = new IndexedWord(token);
                    }
                    // for backwards compatibility - new annotations should have
                    // these fields set, but annotations older than August 2014 might not
                    if (word.DocID() == null && @in.docId != null)
                    {
                        word.SetDocID(@in.docId);
                    }
                    if (word.SentIndex() < 0 && @in.sentIndex >= 0)
                    {
                        word.SetSentIndex(@in.sentIndex);
                    }
                    if (word.Index() < 0 && @in.index >= 0)
                    {
                        word.SetIndex(@in.index);
                    }
                    nodeMap.Put(word.Index(), word.CopyCount(), word);
                    graph.AddVertex(word);
                    if (@in.isRoot)
                    {
                        graph.AddRoot(word);
                    }
                }
                // add all edges to the actual graph
                foreach (AnnotationSerializer.IntermediateEdge ie in edges)
                {
                    IndexedWord source = nodeMap.Get(ie.source, ie.sourceCopy);
                    if (source == null)
                    {
                        throw new RuntimeIOException("Failed to find node " + ie.source + "-" + ie.sourceCopy);
                    }
                    IndexedWord target = nodeMap.Get(ie.target, ie.targetCopy);
                    if (target == null)
                    {
                        throw new RuntimeIOException("Failed to find node " + ie.target + "-" + ie.targetCopy);
                    }
                    // assert(target != null);
                    lock (Lock)
                    {
                        // this is not thread-safe: there are static fields in GrammaticalRelation
                        GrammaticalRelation rel = GrammaticalRelation.ValueOf(ie.dep);
                        graph.AddEdge(source, target, rel, 1.0, ie.isExtra);
                    }
                }
                // compute root nodes if they weren't stored in the graph
                if (!graph.IsEmpty() && graph.GetRoots().Count == 0)
                {
                    graph.ResetRoots();
                }
                return(graph);
            }
Beispiel #18
0
        /// <summary>Fix some bizarre peculiarities with certain trees.</summary>
        /// <remarks>
        /// Fix some bizarre peculiarities with certain trees.
        /// So far, these include:
        /// <ul>
        /// <li>Sometimes there's a node from a word to itself. This seems wrong.</li>
        /// </ul>
        /// </remarks>
        /// <param name="tree">The tree to clean (in place!).</param>
        /// <returns>A list of extra edges, which are valid but were removed.</returns>
        public static IList <SemanticGraphEdge> CleanTree(SemanticGraph tree)
        {
            //    assert !isCyclic(tree);
            // Clean nodes
            IList <IndexedWord> toDelete = new List <IndexedWord>();

            foreach (IndexedWord vertex in tree.VertexSet())
            {
                // Clean punctuation
                if (vertex.Tag() == null)
                {
                    continue;
                }
                char tag = vertex.BackingLabel().Tag()[0];
                if (tag == '.' || tag == ',' || tag == '(' || tag == ')' || tag == ':')
                {
                    if (!tree.OutgoingEdgeIterator(vertex).MoveNext())
                    {
                        // This should really never happen, but it does.
                        toDelete.Add(vertex);
                    }
                }
            }
            toDelete.ForEach(null);
            // Clean edges
            IEnumerator <SemanticGraphEdge> iter = tree.EdgeIterable().GetEnumerator();
            IList <Triple <IndexedWord, IndexedWord, SemanticGraphEdge> > toAdd = new List <Triple <IndexedWord, IndexedWord, SemanticGraphEdge> >();

            toDelete.Clear();
            while (iter.MoveNext())
            {
                SemanticGraphEdge edge = iter.Current;
                if (edge.GetDependent().Index() == edge.GetGovernor().Index())
                {
                    // Clean up copy-edges
                    if (edge.GetDependent().IsCopy(edge.GetGovernor()))
                    {
                        foreach (SemanticGraphEdge toCopy in tree.OutgoingEdgeIterable(edge.GetDependent()))
                        {
                            toAdd.Add(Triple.MakeTriple(edge.GetGovernor(), toCopy.GetDependent(), toCopy));
                        }
                        toDelete.Add(edge.GetDependent());
                    }
                    if (edge.GetGovernor().IsCopy(edge.GetDependent()))
                    {
                        foreach (SemanticGraphEdge toCopy in tree.OutgoingEdgeIterable(edge.GetGovernor()))
                        {
                            toAdd.Add(Triple.MakeTriple(edge.GetDependent(), toCopy.GetDependent(), toCopy));
                        }
                        toDelete.Add(edge.GetGovernor());
                    }
                    // Clean self-edges
                    iter.Remove();
                }
                else
                {
                    if (edge.GetRelation().ToString().Equals("punct"))
                    {
                        // Clean punctuation (again)
                        if (!tree.OutgoingEdgeIterator(edge.GetDependent()).MoveNext())
                        {
                            // This should really never happen, but it does.
                            iter.Remove();
                        }
                    }
                }
            }
            // (add edges we wanted to add)
            toDelete.ForEach(null);
            foreach (Triple <IndexedWord, IndexedWord, SemanticGraphEdge> edge_1 in toAdd)
            {
                tree.AddEdge(edge_1.first, edge_1.second, edge_1.third.GetRelation(), edge_1.third.GetWeight(), edge_1.third.IsExtra());
            }
            // Handle extra edges.
            // Two cases:
            // (1) the extra edge is a subj/obj edge and the main edge is a conj:.*
            //     in this case, keep the extra
            // (2) otherwise, delete the extra
            IList <SemanticGraphEdge> extraEdges = new List <SemanticGraphEdge>();

            foreach (SemanticGraphEdge edge_2 in tree.EdgeIterable())
            {
                if (edge_2.IsExtra())
                {
                    IList <SemanticGraphEdge> incomingEdges = tree.IncomingEdgeList(edge_2.GetDependent());
                    SemanticGraphEdge         toKeep        = null;
                    foreach (SemanticGraphEdge candidate in incomingEdges)
                    {
                        if (toKeep == null)
                        {
                            toKeep = candidate;
                        }
                        else
                        {
                            if (toKeep.GetRelation().ToString().StartsWith("conj") && candidate.GetRelation().ToString().Matches(".subj.*|.obj.*"))
                            {
                                toKeep = candidate;
                            }
                            else
                            {
                                if (!candidate.IsExtra() && !(candidate.GetRelation().ToString().StartsWith("conj") && toKeep.GetRelation().ToString().Matches(".subj.*|.obj.*")))
                                {
                                    toKeep = candidate;
                                }
                            }
                        }
                    }
                    foreach (SemanticGraphEdge candidate_1 in incomingEdges)
                    {
                        if (candidate_1 != toKeep)
                        {
                            extraEdges.Add(candidate_1);
                        }
                    }
                }
            }
            extraEdges.ForEach(null);
            // Add apposition edges (simple coref)
            foreach (SemanticGraphEdge extraEdge in new List <SemanticGraphEdge>(extraEdges))
            {
                // note[gabor] prevent concurrent modification exception
                foreach (SemanticGraphEdge candidateAppos in tree.IncomingEdgeIterable(extraEdge.GetDependent()))
                {
                    if (candidateAppos.GetRelation().ToString().Equals("appos"))
                    {
                        extraEdges.Add(new SemanticGraphEdge(extraEdge.GetGovernor(), candidateAppos.GetGovernor(), extraEdge.GetRelation(), extraEdge.GetWeight(), extraEdge.IsExtra()));
                    }
                }
                foreach (SemanticGraphEdge candidateAppos_1 in tree.OutgoingEdgeIterable(extraEdge.GetDependent()))
                {
                    if (candidateAppos_1.GetRelation().ToString().Equals("appos"))
                    {
                        extraEdges.Add(new SemanticGraphEdge(extraEdge.GetGovernor(), candidateAppos_1.GetDependent(), extraEdge.GetRelation(), extraEdge.GetWeight(), extraEdge.IsExtra()));
                    }
                }
            }
            // Brute force ensure tree
            // Remove incoming edges from roots
            IList <SemanticGraphEdge> rootIncomingEdges = new List <SemanticGraphEdge>();

            foreach (IndexedWord root in tree.GetRoots())
            {
                foreach (SemanticGraphEdge incomingEdge in tree.IncomingEdgeIterable(root))
                {
                    rootIncomingEdges.Add(incomingEdge);
                }
            }
            rootIncomingEdges.ForEach(null);
            // Loop until it becomes a tree.
            bool changed = true;

            while (changed)
            {
                // I just want trees to be trees; is that so much to ask!?
                changed = false;
                IList <IndexedWord>       danglingNodes = new List <IndexedWord>();
                IList <SemanticGraphEdge> invalidEdges  = new List <SemanticGraphEdge>();
                foreach (IndexedWord vertex_1 in tree.VertexSet())
                {
                    // Collect statistics
                    IEnumerator <SemanticGraphEdge> incomingIter = tree.IncomingEdgeIterator(vertex_1);
                    bool hasIncoming         = incomingIter.MoveNext();
                    bool hasMultipleIncoming = false;
                    if (hasIncoming)
                    {
                        incomingIter.Current;
                        hasMultipleIncoming = incomingIter.MoveNext();
                    }
                    // Register actions
                    if (!hasIncoming && !tree.GetRoots().Contains(vertex_1))
                    {
                        danglingNodes.Add(vertex_1);
                    }
                    else
                    {
                        if (hasMultipleIncoming)
                        {
                            foreach (SemanticGraphEdge edge in new IterableIterator <SemanticGraphEdge>(incomingIter))
                            {
                                invalidEdges.Add(edge_2);
                            }
                        }
                    }
                }
                // Perform actions
                foreach (IndexedWord vertex_2 in danglingNodes)
                {
                    tree.RemoveVertex(vertex_2);
                    changed = true;
                }
                foreach (SemanticGraphEdge edge_3 in invalidEdges)
                {
                    tree.RemoveEdge(edge_3);
                    changed = true;
                }
            }
            // Edge case: remove duplicate dobj to "that."
            //            This is a common parse error.
            foreach (IndexedWord vertex_3 in tree.VertexSet())
            {
                SemanticGraphEdge thatEdge = null;
                int dobjCount = 0;
                foreach (SemanticGraphEdge edge in tree.OutgoingEdgeIterable(vertex_3))
                {
                    if (Sharpen.Runtime.EqualsIgnoreCase("that", edge_2.GetDependent().Word()))
                    {
                        thatEdge = edge_2;
                    }
                    if ("dobj".Equals(edge_2.GetRelation().ToString()))
                    {
                        dobjCount += 1;
                    }
                }
                if (dobjCount > 1 && thatEdge != null)
                {
                    // Case: there are two dobj edges, one of which goes to the word "that"
                    // Action: rewrite the dobj edge to "that" to be a "mark" edge.
                    tree.RemoveEdge(thatEdge);
                    tree.AddEdge(thatEdge.GetGovernor(), thatEdge.GetDependent(), GrammaticalRelation.ValueOf(thatEdge.GetRelation().GetLanguage(), "mark"), thatEdge.GetWeight(), thatEdge.IsExtra());
                }
            }
            // Return
            System.Diagnostics.Debug.Assert(IsTree(tree));
            return(extraEdges);
        }
Beispiel #19
0
 /// <summary>Returns all of the entailed shortened clauses (as per natural logic) from the given clause.</summary>
 /// <remarks>
 /// Returns all of the entailed shortened clauses (as per natural logic) from the given clause.
 /// This runs the forward entailment component of the OpenIE system only.
 /// It is usually chained together with the clause splitting component:
 /// <see cref="ClausesInSentence(Edu.Stanford.Nlp.Util.ICoreMap)"/>
 /// .
 /// </remarks>
 /// <param name="clause">The premise clause, as a sentence fragment in itself.</param>
 /// <returns>A list of entailed clauses.</returns>
 public virtual IList <SentenceFragment> EntailmentsFromClause(SentenceFragment clause)
 {
     if (clause.parseTree.IsEmpty())
     {
         return(Java.Util.Collections.EmptyList());
     }
     else
     {
         // Get the forward entailments
         IList <SentenceFragment> list = new List <SentenceFragment>();
         if (entailmentsPerSentence > 0)
         {
             Sharpen.Collections.AddAll(list, forwardEntailer.Apply(clause.parseTree, true).Search().Stream().Map(null).Collect(Collectors.ToList()));
         }
         list.Add(clause);
         // A special case for adjective entailments
         IList <SentenceFragment> adjFragments = new List <SentenceFragment>();
         SemgrexMatcher           matcher      = adjectivePattern.Matcher(clause.parseTree);
         while (matcher.Find())
         {
             // (get nodes)
             IndexedWord subj = matcher.GetNode("subj");
             IndexedWord be   = matcher.GetNode("be");
             IndexedWord adj  = matcher.GetNode("adj");
             IndexedWord obj  = matcher.GetNode("obj");
             IndexedWord pobj = matcher.GetNode("pobj");
             string      prep = matcher.GetRelnString("prep");
             // (if the adjective, or any earlier adjective, is privative, then all bets are off)
             foreach (SemanticGraphEdge edge in clause.parseTree.OutgoingEdgeIterable(obj))
             {
                 if ("amod".Equals(edge.GetRelation().ToString()) && edge.GetDependent().Index() <= adj.Index() && Edu.Stanford.Nlp.Naturalli.Util.PrivativeAdjectives.Contains(edge.GetDependent().Word().ToLower()))
                 {
                     goto OUTER_continue;
                 }
             }
             // (create the core tree)
             SemanticGraph tree = new SemanticGraph();
             tree.AddRoot(adj);
             tree.AddVertex(subj);
             tree.AddVertex(be);
             tree.AddEdge(adj, be, GrammaticalRelation.ValueOf(Language.English, "cop"), double.NegativeInfinity, false);
             tree.AddEdge(adj, subj, GrammaticalRelation.ValueOf(Language.English, "nsubj"), double.NegativeInfinity, false);
             // (add pp attachment, if it existed)
             if (pobj != null)
             {
                 System.Diagnostics.Debug.Assert(prep != null);
                 tree.AddEdge(adj, pobj, GrammaticalRelation.ValueOf(Language.English, prep), double.NegativeInfinity, false);
             }
             // (check for monotonicity)
             if (adj.Get(typeof(NaturalLogicAnnotations.PolarityAnnotation)).IsUpwards() && be.Get(typeof(NaturalLogicAnnotations.PolarityAnnotation)).IsUpwards())
             {
                 // (add tree)
                 adjFragments.Add(new SentenceFragment(tree, clause.assumedTruth, false));
             }
             OUTER_continue :;
         }
         OUTER_break :;
         Sharpen.Collections.AddAll(list, adjFragments);
         return(list);
     }
 }