/// <summary> /// Gets a copy of this collection /// </summary> /// <returns>Copy of this collection</returns> public override LabeledNodeCollection Copy() { // create copy PropBankLabeledNodeCollection copy = new PropBankLabeledNodeCollection(new PropBankNodeLabel(_label.Type, _label.Feature, _label.Confidence)); // add single nodes foreach (TreeBankNode singleNode in SingleNodes) { copy.AddSingleNode(singleNode); } // add split nodes foreach (List <TreeBankNode> splitNode in SplitNodes) { copy.AddSplitNode(splitNode); } return(copy); }
/// <summary> /// Sets the label on this node /// </summary> /// <param name="label">Label to use</param> /// <param name="syncWithRootNodeCollection">Whether or not to add this node to the corresponding node collection on the root. The /// root collections are shortcut collections that allow quick searching for particular node types. Thus, the collections need to /// remain synchronized with the labels that are applied to the nodes. Passing true here will perform this synchronization. If you /// will do the synchronization on your own later, pass false.</param> public void SetLabel(PropBankNodeLabel label, bool syncWithRootNodeCollection) { // first remove current node from previous node collection if it is present if (_label != null) { PropBankLabeledNodeCollection nodes = GetLabeledNodeCollection(label, false); if (nodes != null && nodes.ContainsSingleNode(this)) { nodes.RemoveSingleNode(this); } } _label = label; // add node to root's collection if needed if (syncWithRootNodeCollection) { GetLabeledNodeCollection(_label, true).AddSingleNode(this); } }
/// <summary> /// Gets labeled node collection /// </summary> /// <param name="label">Label of node collection to get</param> /// <param name="createIfMissing">Whether or not to create and return a new node collection if none exists</param> /// <returns>Labeled node collection</returns> public PropBankLabeledNodeCollection GetLabeledNodeCollection(PropBankNodeLabel label, bool createIfMissing) { // look for an existing collection with the given label foreach (PropBankLabeledNodeCollection nodeCollection in LabeledNodeCollections) { if (nodeCollection.Label == label) { return(nodeCollection); } } if (!createIfMissing) { return(null); } // return new collection PropBankLabeledNodeCollection newCollection = new PropBankLabeledNodeCollection(label); LabeledNodeCollections.Add(newCollection); return(newCollection); }
/// <summary> /// Gets a predicate tree for a PropBank propositions entry /// </summary> /// <param name="vi">VerbInfo specifying tree to look up</param> /// <returns>PropBankNode</returns> public PropBankNode GetPropBankTree(VerbInfo vi) { TreeBankNode parse = GetParseTree(vi.File, vi.SentenceNumber); PropBankNode predTree = new PropBankNode(parse); predTree.Information = vi; // label information is space-delimited string[] labels = vi.LabeledNodeLocations.Split(' '); foreach (string label in labels) { // label columns are dash-delimited string[] labelCols = label.Split('-'); // get label type PropBankNodeLabel.NodeType labelType = PropBankNodeLabel.GetNodeType(labelCols[1]); // get label feature if any PropBankNodeLabel.NodeFeature labelFeature = PropBankNodeLabel.NodeFeature.None; if (labelCols.Length > 2) { // sometimes the feature is the actual preposition, so this might fail string featureStr = labelCols[2]; if (!PropBankNodeLabel.TryGetNodeFeature(featureStr, out labelFeature)) { // use PRP as the feature, which we have added for this case featureStr = "PRP"; labelFeature = PropBankNodeLabel.GetNodeFeature(featureStr); } if (labelCols.Length > 3) { throw new Exception("Missed feature"); } } // create new labeled node collection PropBankLabeledNodeCollection labeledNodes = new PropBankLabeledNodeCollection(new PropBankNodeLabel(labelType, labelFeature, 1)); AddNodesToCollection(predTree, labelCols[0], labeledNodes); // add to root's list of nodes predTree.LabeledNodeCollections.Add(labeledNodes); } // make sure one of the predicate leaves has the leaf number from the propositions file entry bool foundMatch = false; foreach (PropBankNode predicateNode in predTree.PredicateNodes) { foreach (PropBankNode leaf in predicateNode.Leaves) { if (leaf.LeafNumber == vi.LeafNumber) { foundMatch = true; break; } } if (foundMatch) { break; } } if (!foundMatch) { throw new Exception("Mismatch between VerbInfo predicate leaf number and actual predicate leaf number"); } return(predTree); }
/// <summary> /// Marks argument nodes from the current node in the corresponding parse from a different TreeBank. This is used when /// transferring PropBank annotations to parse trees other than those distributed in the TreeBank (e.g., those produced /// by an automatic syntactic parser). /// </summary> /// <param name="treeBankEngine">Initialized TreeBank engine from which to pull the parse tree to mark PropBank arguments within</param> /// <returns>PropBank node, or null if all arguments couldn't be minimally transferred to the other parse tree. An argument /// is minimally transferred if the corresponding node in the other parse tree subsumes precisely the same text as the node in the /// current parse tree. Sometimes this is not possible due to parse errors.</returns> public PropBankNode MarkArgumentNodesIn(TreeBankEngine treeBankEngine) { if (!IsRoot) { throw new Exception("Attempted to transform non-root node"); } // get mrg file in other tree bank string treeBankMrgFile = treeBankEngine.GetFullMrgPath(MrgFile.Substring(MrgFile.LastIndexOf(Path.DirectorySeparatorChar) + 1)); // need a PropBank root to mark arguments within PropBankNode pbRoot = new PropBankNode(treeBankEngine.GetParseTree(treeBankMrgFile, SentenceNumber)); // make sure we got the right sentence if (pbRoot.SurfaceText != SurfaceText) { throw new Exception("Failed to convert root to Charniak-parsed version"); } // Add information to root. Ignore leaf number and argument info for now - we'll set them at the end. treeBankMrgFile = treeBankMrgFile.Substring(treeBankEngine.MrgPath.Length); VerbInfo pbInfo = Information; pbRoot.Information = new VerbInfo(pbInfo.Verb, treeBankMrgFile, pbInfo.SentenceNumber, -1, pbInfo.Tagger, pbInfo.RoleSetId, pbInfo.VForm, pbInfo.VTense, pbInfo.VAspect, pbInfo.VPerson, pbInfo.VVoice, ""); // transfer all argument node lists foreach (PropBankLabeledNodeCollection nodeCollection in LabeledNodeCollections) { // new node collection PropBankLabeledNodeCollection otherNodeCollection = new PropBankLabeledNodeCollection(new PropBankNodeLabel(nodeCollection.Label.Type, nodeCollection.Label.Feature, nodeCollection.Label.Confidence)); // get single nodes foreach (PropBankNode singleNode in nodeCollection.SingleNodes) { if (!singleNode.IsNullElement) { // get argument node from other parse tree PropBankNode otherArgNode = (PropBankNode)pbRoot.GetMinimallySubsumingNode(singleNode.FirstToken, singleNode.LastToken); if (otherArgNode == null) { return(null); } otherNodeCollection.AddSingleNode(otherArgNode); } } // get split arguments foreach (List <TreeBankNode> splitArg in nodeCollection.SplitNodes) { List <TreeBankNode> otherSplitArg = new List <TreeBankNode>(); // get each node in the split argument foreach (PropBankNode splitArgNode in splitArg) { if (!splitArgNode.IsNullElement) { // get split node in other tree PropBankNode otherSplitArgNode = (PropBankNode)pbRoot.GetMinimallySubsumingNode(splitArgNode.FirstToken, splitArgNode.LastToken); if (otherSplitArgNode == null) { return(null); } otherSplitArg.Add(otherSplitArgNode); } } // if only one node of the split arg was non-null, at that node as a single if (otherSplitArg.Count == 1) { otherNodeCollection.AddSingleNode(otherSplitArg.First()); } // otherwise, add the split arg normally else if (otherSplitArg.Count >= 2) { otherNodeCollection.AddSplitNode(otherSplitArg); } } // add coref list if we found non-null nodes if (otherNodeCollection.SingleNodes.Count > 0 || otherNodeCollection.SplitNodes.Count > 0) { pbRoot.LabeledNodeCollections.Add(otherNodeCollection); } } // return null if we didn't find any argument node lists with non-null nodes if (pbRoot.LabeledNodeCollections.Count == 0) { return(null); } // set leaf number and argument information pbRoot.Information.LeafNumber = pbRoot.PredicateNodes.First().Leaves[0].LeafNumber; pbRoot.Information.LabeledNodeLocations = pbRoot.LabeledNodeLocations; return(pbRoot); }