Ejemplo n.º 1
0
        /// <summary>
        /// Adds a frame element to this set
        /// </summary>
        /// <param name="frameElement">Frame element to add</param>
        public void Add(FrameElement frameElement)
        {
            _frameElements.Add(frameElement);
            _idFrameElement.Add(frameElement.ID, frameElement);

            string lowerName = frameElement.Name.ToLower();

            _nameFrameElements.EnsureContainsKey(lowerName, typeof(Set <FrameElement>));
            _nameFrameElements[lowerName].Add(frameElement);
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Equals override
        /// </summary>
        /// <param name="obj">Object to compare this one to</param>
        /// <returns>True if object is a FE with the same ID, False otherwise</returns>
        public override bool Equals(object obj)
        {
            if (!(obj is FrameElement))
            {
                return(false);
            }

            FrameElement fe = obj as FrameElement;

            return(_id == fe.ID);
        }
Ejemplo n.º 3
0
 /// <summary>
 /// Removes a frae element from this set
 /// </summary>
 /// <param name="frameElement">Frame element to remove</param>
 public void Remove(FrameElement frameElement)
 {
     _frameElements.Remove(frameElement);
     _idFrameElement.Remove(frameElement.ID);
     _nameFrameElements[frameElement.Name.ToLower()].Remove(frameElement);
 }
Ejemplo n.º 4
0
 /// <summary>
 /// Checks for a frame element
 /// </summary>
 /// <param name="frameElement">Frame element to check for</param>
 /// <returns>True if frame element is present and false otherwise</returns>
 public bool Contains(FrameElement frameElement)
 {
     return(_frameElements.Contains(frameElement));
 }
Ejemplo n.º 5
0
        /// <summary>
        /// Gets the shortest network path from the current frame element to another frame element
        /// </summary>
        /// <param name="destinationFrameElement">Destination frame element</param>
        /// <param name="searchRelations">Relations to search</param>
        /// <param name="searchDirection">Relation direction to search</param>
        /// <param name="maxDepth">Maximum depth to search within the network (i.e., maximum distance destination frame element can be from the current one)</param>
        /// <param name="frameElementPath">Path from this frame element to the destination frame element, or null for no path</param>
        /// <param name="relationPath">Relation path between this frame element and the destination frame element, or null for no path</param>
        /// <returns>True if path exists, false otherwise</returns>
        public bool GetShortestPathTo(FrameElement destinationFrameElement,
                                      Set <Frame.FrameRelation> searchRelations,
                                      Frame.FrameRelationDirection searchDirection,
                                      int maxDepth,
                                      out List <FrameElement> frameElementPath,
                                      out List <Frame.FrameRelation> relationPath)
        {
            frameElementPath = null;
            relationPath     = null;

            // breadth-first search originating at the current frame element
            Queue <FrameElement> searchQueue = new Queue <FrameElement>();

            _frameElementSearchBackPointer = null;                        // make sure to null out the source frame element back pointer
            searchQueue.Enqueue(this);

            Set <FrameElement> frameElementsEncountered = new Set <FrameElement>();  // keep track of frame elements we see so we don't enter any cycles

            frameElementsEncountered.Add(this);

            int currentDepth               = 0;  // tracks current search depth
            int nodesAtCurrentDepth        = 1;  // tracks nodes at current search depth
            int nodesAtCurrentDepthPlusOne = 0;  // tracks nodes at one beyond the current search depth

            while (searchQueue.Count > 0 && currentDepth <= maxDepth)
            {
                FrameElement currentFrameElement = searchQueue.Dequeue();

                // check for destination frame element
                if (currentFrameElement == destinationFrameElement)
                {
                    // create path by following backpointers
                    frameElementPath = new List <FrameElement>();
                    relationPath     = new List <Frame.FrameRelation>();
                    while (destinationFrameElement != null)
                    {
                        frameElementPath.Add(destinationFrameElement);

                        // back up to previous frame element
                        FrameElement previousFrameElement = destinationFrameElement.FrameElementSearchBackPointer;

                        // if the previous frame element isn't null, record the relationship
                        if (previousFrameElement != null)
                        {
                            relationPath.Add(destinationFrameElement.FrameRelationSearchBackPointer);
                        }

                        destinationFrameElement = previousFrameElement;
                    }

                    // reverse paths to be from the current to the destination frame elements
                    frameElementPath.Reverse();
                    relationPath.Reverse();

                    if (frameElementPath[0] != this)
                    {
                        throw new Exception("Path should start at current frame element");
                    }

                    if (frameElementPath.Count != relationPath.Count + 1)
                    {
                        throw new Exception("Path length mismatch between frame elements and relations");
                    }

                    if (frameElementPath.Count - 1 > maxDepth)
                    {
                        throw new Exception("Exceeded maximum allowed search depth");
                    }

                    return(true);
                }

                // queue up frame elements related to the current one by any of the given relations
                int nodesAdded = 0;
                foreach (Frame.FrameRelation searchRelation in searchRelations)
                {
                    // add sub-FEs
                    if (searchDirection == Frame.FrameRelationDirection.Sub || searchDirection == Frame.FrameRelationDirection.Both)
                    {
                        foreach (FrameElement subFE in currentFrameElement._relationSubFrameElements[searchRelation])
                        {
                            if (!frameElementsEncountered.Contains(subFE))
                            {
                                subFE._frameElementSearchBackPointer  = currentFrameElement;
                                subFE._frameRelationSearchBackPointer = searchRelation;

                                searchQueue.Enqueue(subFE);
                                frameElementsEncountered.Add(subFE);

                                ++nodesAdded;
                            }
                        }
                    }

                    // add super-FEs
                    if (searchDirection == Frame.FrameRelationDirection.Super || searchDirection == Frame.FrameRelationDirection.Both)
                    {
                        foreach (FrameElement superFE in currentFrameElement._relationSuperFrameElements[searchRelation])
                        {
                            if (!frameElementsEncountered.Contains(superFE))
                            {
                                superFE._frameElementSearchBackPointer  = currentFrameElement;
                                superFE._frameRelationSearchBackPointer = searchRelation;

                                searchQueue.Enqueue(superFE);
                                frameElementsEncountered.Add(superFE);

                                ++nodesAdded;
                            }
                        }
                    }
                }

                // all generated search nodes belong in the next depth level
                nodesAtCurrentDepthPlusOne += nodesAdded;

                // if there aren't any nodes left at the current depth level, move to next level out
                if (--nodesAtCurrentDepth == 0)
                {
                    nodesAtCurrentDepth        = nodesAtCurrentDepthPlusOne;
                    nodesAtCurrentDepthPlusOne = 0;
                    currentDepth++;
                }
            }

            return(false);
        }
Ejemplo n.º 6
0
 /// <summary>
 /// Adds a frame element to the super-FE collection for a relation
 /// </summary>
 /// <param name="frameElement">Frame element to add</param>
 /// <param name="relation">Relation between current and given frame element</param>
 internal void AddSuperFrameElement(FrameElement frameElement, Frame.FrameRelation relation)
 {
     _relationSuperFrameElements[relation].Add(frameElement);
 }
Ejemplo n.º 7
0
        /// <summary>
        /// Gets annotations for a lexical unit
        /// </summary>
        /// <param name="frame">Frame for which we're getting annotations</param>
        /// <param name="lexicalUnitID">ID of lexical unit for which to get annotations</param>
        /// <returns>Annotation information</returns>
        public List <Attestation> GetAttestations(Frame frame, int lexicalUnitID)
        {
            List <Attestation> attestations = new List <Attestation>();

            // return nothing if no file exists
            string attestationFilePath = Path.Combine(_annotationDirectory, "lu" + lexicalUnitID + ".xml");

            if (!File.Exists(attestationFilePath))
            {
                return(attestations);
            }

            // constraints to skip to FE layer
            Dictionary <string, string> feAttributeConstraints = new Dictionary <string, string>();

            feAttributeConstraints.Add("name", "FE");

            // constraints to skip to Target layer
            Dictionary <string, string> targetAttributeConstraints = new Dictionary <string, string>();

            targetAttributeConstraints.Add("name", "Target");

            // get all attestations
            XmlParser attestationP = new XmlParser(File.ReadAllText(attestationFilePath));

            if (_version == FrameNetEngine.Version.FrameNet_1_3)
            {
                string annotationSetXML;
                while ((annotationSetXML = attestationP.OuterXML("annotationSet")) != null)
                {
                    Attestation annotation = new Attestation();

                    // parser for entire annotation set
                    XmlParser annotationSetP = new XmlParser(annotationSetXML);

                    // first get sentence...it is below the annotation layers
                    annotation.Sentence = new XmlParser(annotationSetP.OuterXML("sentence")).ElementText("text").Trim();

                    #region get fe bindings
                    // parser is forward-only, so rewind
                    annotationSetP.Reset();

                    // get FE bindings
                    if (!annotationSetP.SkipToElement("layer", feAttributeConstraints))
                    {
                        throw new Exception("Failed to find FE layer in annotation set");
                    }

                    string    feBindingXML = annotationSetP.OuterXML("layer");
                    XmlParser feBindingP   = new XmlParser(feBindingXML);

                    // read off FE binding labels
                    string labelXML;
                    while ((labelXML = feBindingP.OuterXML("label")) != null)
                    {
                        XmlParser labelP = new XmlParser(labelXML);

                        // skip null instantiations, which don't have start/end values
                        if (!labelP.GetAttributeNames("label").Contains("start"))
                        {
                            continue;
                        }

                        // get annotated span of text
                        int           feStart = int.Parse(labelP.AttributeValue("label", "start"));
                        int           feEnd   = int.Parse(labelP.AttributeValue("label", "end"));
                        string        feText  = annotation.Sentence.Substring(feStart, feEnd - feStart + 1);
                        AnnotatedSpan span    = new AnnotatedSpan(feStart, feText);

                        // add FE binding...we shouldn't have to check for the existence of a frame element, but errors abound!
                        string feName = labelP.AttributeValue("label", "name");
                        if (frame.FrameElements.Contains(feName))
                        {
                            FrameElement fe = frame.FrameElements.Get(feName);
                            annotation.FrameElementBindings.EnsureContainsKey(fe, typeof(List <AnnotatedSpan>));
                            annotation.FrameElementBindings[fe].Add(span);
                        }
                    }
                    #endregion

                    #region targets
                    // get target annotation...reset parser...sometimes the target comes before the FE layer
                    annotationSetP.Reset();

                    if (!annotationSetP.SkipToElement("layer", targetAttributeConstraints))
                    {
                        throw new Exception("Failed to find target layer in annotation set");
                    }

                    // read all targets
                    XmlParser targetP = new XmlParser(annotationSetP.OuterXML("layer"));
                    while ((labelXML = targetP.OuterXML("label")) != null)
                    {
                        XmlParser labelP      = new XmlParser(labelXML);
                        int       targetStart = int.Parse(labelP.AttributeValue("label", "start"));
                        int       targetEnd   = int.Parse(labelP.AttributeValue("label", "end"));
                        string    targetText  = annotation.Sentence.Substring(targetStart, targetEnd - targetStart + 1);

                        annotation.Targets.Add(new AnnotatedSpan(targetStart, targetText));
                    }
                    #endregion

                    attestations.Add(annotation);
                }
            }
            else if (_version == FrameNetEngine.Version.FrameNet_1_5)
            {
                string sentenceXML;
                while ((sentenceXML = attestationP.OuterXML("sentence")) != null)
                {
                    Attestation annotation = new Attestation();

                    XmlParser sentenceP = new XmlParser(sentenceXML);
                    annotation.Sentence = sentenceP.ElementText("text").Trim();

                    #region get fe bindings
                    if (!sentenceP.SkipToElement("layer", feAttributeConstraints))
                    {
                        throw new Exception("Failed to find FE layer in annotation set");
                    }

                    // read off FE binding labels
                    XmlParser feBindingP = new XmlParser(sentenceP.OuterXML("layer"));
                    string    labelXML;
                    while ((labelXML = feBindingP.OuterXML("label")) != null)
                    {
                        XmlParser labelP = new XmlParser(labelXML);

                        // skip null instantiations, which don't have start/end values
                        if (!labelP.GetAttributeNames("label").Contains("start"))
                        {
                            continue;
                        }

                        // get annotated span of text
                        int           feStart = int.Parse(labelP.AttributeValue("label", "start"));
                        int           feEnd   = int.Parse(labelP.AttributeValue("label", "end"));
                        string        feText  = annotation.Sentence.Substring(feStart, feEnd - feStart + 1);
                        AnnotatedSpan span    = new AnnotatedSpan(feStart, feText);

                        // add FE binding...we shouldn't have to check for the existence of a frame element, but errors abound!
                        int feID = int.Parse(labelP.AttributeValue("label", "feID"));
                        if (frame.FrameElements.Contains(feID))
                        {
                            FrameElement fe = frame.FrameElements.Get(feID);
                            annotation.FrameElementBindings.EnsureContainsKey(fe, typeof(List <AnnotatedSpan>));
                            annotation.FrameElementBindings[fe].Add(span);
                        }
                    }
                    #endregion

                    #region targets
                    // get target annotation...reset parser...sometimes the target comes before the FE layer
                    sentenceP.Reset();

                    if (!sentenceP.SkipToElement("layer", targetAttributeConstraints))
                    {
                        throw new Exception("Failed to find target layer in annotation set");
                    }

                    // read all targets
                    XmlParser targetP = new XmlParser(sentenceP.OuterXML("layer"));
                    while ((labelXML = targetP.OuterXML("label")) != null)
                    {
                        XmlParser labelP      = new XmlParser(labelXML);
                        int       targetEnd   = int.Parse(labelP.AttributeValue("label", "end"));
                        int       targetStart = int.Parse(labelP.AttributeValue("label", "start"));

                        // bug in framenet:  bad sentence
                        if (targetStart >= annotation.Sentence.Length || targetEnd >= annotation.Sentence.Length)
                        {
                            continue;
                        }

                        string targetText = annotation.Sentence.Substring(targetStart, targetEnd - targetStart + 1);

                        annotation.Targets.Add(new AnnotatedSpan(targetStart, targetText));
                    }
                    #endregion

                    attestations.Add(annotation);
                }
            }
            else
            {
                throw new Exception("Unrecognized FrameNet version:  " + _version);
            }

            return(attestations);
        }
Ejemplo n.º 8
0
        /// <summary>
        /// Constructor
        /// </summary>
        /// <param name="frameNetDirectory">Path to FrameNet distribution directory</param>
        /// <param name="version">FrameNet version</param>
        public FrameNetEngine(string frameNetDirectory, Version version)
        {
            if (!System.IO.Directory.Exists(frameNetDirectory))
            {
                throw new DirectoryNotFoundException("Invalid FrameNet directory");
            }

            _frameNameFrame             = new Dictionary <string, Frame>();
            _frameElementIdFrameElement = new Dictionary <int, FrameElement>();
            _lexemeLexicalUnitIDs       = new Dictionary <string, Set <int> >();
            _lexicalUnitIdFrame         = new Dictionary <int, Frame>();
            _lexicalUnitLexicalUnitIDs  = new Dictionary <string, Set <int> >();
            _lexicalUnitIdLexicalUnit   = new Dictionary <int, LexicalUnit>();

            if (version == Version.FrameNet_1_3)
            {
                // init annotation engine
                _lexicalUnitAnnotationEngine = new LexicalUnitAnnotationEngine(LAIR.CommonPort.IO.Directory.FindDirectory(frameNetDirectory, "luXML"), version);

                #region get frames
                Set <int> uniqueFrameIDCheck = new Set <int>();
                XmlParser framesP            = new XmlParser(System.IO.File.ReadAllText(LAIR.CommonPort.IO.Directory.FindFile(frameNetDirectory, "frames.xml")));
                while (framesP.SkipToElement("frame"))
                {
                    // create frame
                    string    frameXML        = framesP.OuterXML("frame");
                    XmlParser frameP          = new XmlParser(frameXML);
                    int       frameID         = int.Parse(frameP.AttributeValue("frame", "ID"));
                    string    frameName       = frameP.AttributeValue("frame", "name").ToLower().Trim(); // use lowercase for all frame names
                    string    frameDefinition = frameP.ElementText("definition");
                    Frame     frame           = new Frame(frameName, frameDefinition, frameID);

                    // add to frame index index
                    _frameNameFrame.Add(frame.Name, frame);
                    uniqueFrameIDCheck.Add(frame.ID);

                    // get frame elements
                    string    fesXML = frameP.OuterXML("fes");
                    XmlParser fesP   = new XmlParser(fesXML);
                    string    feXML;
                    while ((feXML = fesP.OuterXML("fe")) != null)
                    {
                        // get frame element
                        XmlParser    feParser = new XmlParser(feXML);
                        int          feID     = int.Parse(feParser.AttributeValue("fe", "ID"));
                        string       feName   = feParser.AttributeValue("fe", "name").Trim().ToLower();
                        string       feDef    = feParser.ElementText("definition");
                        FrameElement fe       = new FrameElement(feID, feName, feDef, frame);
                        frame.FrameElements.Add(fe);

                        // add to index
                        _frameElementIdFrameElement.Add(fe.ID, fe);
                    }

                    // get lexical units
                    string    lusXML    = frameP.OuterXML("lexunits");
                    XmlParser lusParser = new XmlParser(lusXML);
                    string    luXML;
                    while ((luXML = lusParser.OuterXML("lexunit")) != null)
                    {
                        XmlParser luParser = new XmlParser(luXML);
                        int       luID     = int.Parse(luParser.AttributeValue("lexunit", "ID"));
                        string    luName   = luParser.AttributeValue("lexunit", "name");
                        luName = luName.Substring(0, luName.IndexOf('.'));
                        string luPos = luParser.AttributeValue("lexunit", "pos");
                        string luDef = luParser.ElementText("definition");

                        // get lexemes for this lexunit...we may get duplicates...don't worry about them
                        Set <Lexeme> lexemes    = new Set <Lexeme>(false);
                        string       lexemesXML = luParser.OuterXML("lexemes");
                        XmlParser    lexemesP   = new XmlParser(lexemesXML);
                        string       lexemeXML;
                        while ((lexemeXML = lexemesP.OuterXML("lexeme")) != null)
                        {
                            XmlParser lexemeP     = new XmlParser(lexemeXML);
                            string    pos         = lexemeP.AttributeValue("lexeme", "pos");
                            bool      breakBefore = bool.Parse(lexemeP.AttributeValue("lexeme", "breakBefore"));
                            bool      head        = bool.Parse(lexemeP.AttributeValue("lexeme", "headword"));
                            string    value       = lexemeP.ElementText("lexeme");

                            lexemes.Add(new Lexeme(value, pos, breakBefore, head));
                        }

                        // create lexical unit and add to frame
                        LexicalUnit lexicalUnit = new LexicalUnit(luID, luName, luPos, luDef, lexemes);

                        frame.LexicalUnits.Add(lexicalUnit);

                        // add map from full lexeme string to lexical unit id
                        string lexemeString = lexicalUnit.ToString();
                        _lexemeLexicalUnitIDs.EnsureContainsKey(lexemeString, typeof(Set <int>), false);
                        _lexemeLexicalUnitIDs[lexemeString].Add(luID);

                        // add map from lexical unit to frame
                        _lexicalUnitIdFrame.Add(lexicalUnit.ID, frame);

                        // add map from lexical unit to lexical unit id
                        _lexicalUnitLexicalUnitIDs.EnsureContainsKey(lexicalUnit.Name, typeof(Set <int>));
                        _lexicalUnitLexicalUnitIDs[lexicalUnit.Name].Add(lexicalUnit.ID);

                        // add map from lexical unit ID to lexical unit
                        _lexicalUnitIdLexicalUnit.Add(lexicalUnit.ID, lexicalUnit);
                    }
                }
                #endregion

                #region get frame relations
                framesP = new XmlParser(System.IO.File.ReadAllText(LAIR.CommonPort.IO.Directory.FindFile(frameNetDirectory, "frRelation.xml")));
                string relationsXML;
                while ((relationsXML = framesP.OuterXML("frame-relation-type")) != null)
                {
                    // get relation type
                    XmlParser           relationsP = new XmlParser(relationsXML);
                    Frame.FrameRelation relation   = Frame.GetFrameRelation(relationsP.AttributeValue("frame-relation-type", "name"));

                    string relationXML;
                    while ((relationXML = relationsP.OuterXML("frame-relation")) != null)
                    {
                        XmlParser relationP      = new XmlParser(relationXML);
                        string    superFrameName = relationP.AttributeValue("frame-relation", "superFrameName").ToLower();
                        string    subFrameName   = relationP.AttributeValue("frame-relation", "subFrameName").ToLower();

                        Frame superFrame = _frameNameFrame[superFrameName];
                        Frame subFrame   = _frameNameFrame[subFrameName];

                        superFrame.GetSubFrames(relation).Add(subFrame);
                        subFrame.GetSuperFrames(relation).Add(superFrame);

                        // add FE relations
                        while (relationP.SkipToElement("fe-relation"))
                        {
                            int superFeID = int.Parse(relationP.AttributeValue("fe-relation", "supId"));
                            int subFeID   = int.Parse(relationP.AttributeValue("fe-relation", "subId"));

                            FrameElement superFE = superFrame.FrameElements.Get(superFeID);
                            FrameElement subFE   = subFrame.FrameElements.Get(subFeID);

                            superFE.AddSubFrameElement(subFE, relation);
                            subFE.AddSuperFrameElement(superFE, relation);
                        }
                    }
                }
                #endregion
            }
            else if (version == Version.FrameNet_1_5)
            {
                // init annotation engine
                _lexicalUnitAnnotationEngine = new LexicalUnitAnnotationEngine(LAIR.CommonPort.IO.Directory.FindDirectory(frameNetDirectory, "lu"), version);

                #region get frames
                Set <int> uniqueFrameIDCheck = new Set <int>();
                foreach (string framePath in System.IO.Directory.GetFiles(LAIR.CommonPort.IO.Directory.FindDirectory(frameNetDirectory, "frame"), "*.xml"))
                {
                    // create frame
                    XmlParser frameP          = new XmlParser(System.IO.File.ReadAllText(framePath));
                    int       frameID         = int.Parse(frameP.AttributeValue("frame", "ID"));
                    string    frameName       = frameP.AttributeValue("frame", "name").ToLower().Trim(); // use lowercase for all frame names
                    string    frameDefinition = frameP.ElementText("definition");
                    Frame     frame           = new Frame(frameName, frameDefinition, frameID);

                    // add to frame index index
                    _frameNameFrame.Add(frame.Name, frame);
                    uniqueFrameIDCheck.Add(frame.ID);

                    // get frame elements
                    string feXML;
                    while ((feXML = frameP.OuterXML("FE")) != null)
                    {
                        // get frame element
                        XmlParser    feParser = new XmlParser(feXML);
                        int          feID     = int.Parse(feParser.AttributeValue("FE", "ID"));
                        string       feName   = feParser.AttributeValue("FE", "name").Trim().ToLower();
                        string       feDef    = feParser.ElementText("definition");
                        FrameElement fe       = new FrameElement(feID, feName, feDef, frame);
                        frame.FrameElements.Add(fe);

                        // add to index
                        _frameElementIdFrameElement.Add(fe.ID, fe);
                    }

                    // get lexical units
                    frameP.Reset();
                    string luXML;
                    while ((luXML = frameP.OuterXML("lexUnit")) != null)
                    {
                        XmlParser luParser = new XmlParser(luXML);

                        string luPos  = luParser.AttributeValue("lexUnit", "POS");
                        string luName = luParser.AttributeValue("lexUnit", "name");
                        luName = luName.Substring(0, luName.IndexOf('.'));
                        int    luID  = int.Parse(luParser.AttributeValue("lexUnit", "ID"));
                        string luDef = luParser.ElementText("definition");

                        // get lexemes for this lexunit...we may get duplicates...don't worry about them
                        Set <Lexeme> lexemes = new Set <Lexeme>(false);
                        string       lexemeXML;
                        while ((lexemeXML = luParser.OuterXML("lexeme")) != null)
                        {
                            XmlParser lexemeP     = new XmlParser(lexemeXML);
                            bool      head        = bool.Parse(lexemeP.AttributeValue("lexeme", "headword"));
                            bool      breakBefore = bool.Parse(lexemeP.AttributeValue("lexeme", "breakBefore"));
                            string    pos         = lexemeP.AttributeValue("lexeme", "POS");
                            string    value       = lexemeP.AttributeValue("lexeme", "name");

                            lexemes.Add(new Lexeme(value, pos, breakBefore, head));
                        }

                        // create lexical unit and add to frame
                        LexicalUnit lexicalUnit = new LexicalUnit(luID, luName, luPos, luDef, lexemes);

                        frame.LexicalUnits.Add(lexicalUnit);

                        // add map from full lexeme string to lexical unit id
                        string lexemeString = lexicalUnit.ToString();
                        _lexemeLexicalUnitIDs.EnsureContainsKey(lexemeString, typeof(Set <int>), false);
                        _lexemeLexicalUnitIDs[lexemeString].Add(luID);

                        // add map from lexical unit to frame
                        _lexicalUnitIdFrame.Add(lexicalUnit.ID, frame);

                        // add map from lexical unit to lexical unit id
                        _lexicalUnitLexicalUnitIDs.EnsureContainsKey(lexicalUnit.Name, typeof(Set <int>));
                        _lexicalUnitLexicalUnitIDs[lexicalUnit.Name].Add(lexicalUnit.ID);

                        // add map from lexical unit ID to lexical unit
                        _lexicalUnitIdLexicalUnit.Add(lexicalUnit.ID, lexicalUnit);
                    }
                }
                #endregion

                #region get relations
                XmlParser allRelationsP = new XmlParser(System.IO.File.ReadAllText(LAIR.CommonPort.IO.Directory.FindFile(frameNetDirectory, "frRelation.xml")));
                string    relationsXML;
                while ((relationsXML = allRelationsP.OuterXML("frameRelationType")) != null)
                {
                    // get relation type
                    XmlParser           relationsP = new XmlParser(relationsXML);
                    Frame.FrameRelation relation   = Frame.GetFrameRelation(relationsP.AttributeValue("frameRelationType", "name"));

                    // read each instance of the relation
                    string relationXML;
                    while ((relationXML = relationsP.OuterXML("frameRelation")) != null)
                    {
                        XmlParser relationP = new XmlParser(relationXML);

                        // get related frames
                        Frame subFrame   = _frameNameFrame[relationP.AttributeValue("frameRelation", "subFrameName").ToLower()];
                        Frame superFrame = _frameNameFrame[relationP.AttributeValue("frameRelation", "superFrameName").ToLower()];

                        subFrame.GetSuperFrames(relation).Add(superFrame);
                        superFrame.GetSubFrames(relation).Add(subFrame);

                        // add FE relations
                        while (relationP.SkipToElement("FERelation"))
                        {
                            FrameElement subFE   = subFrame.FrameElements.Get(int.Parse(relationP.AttributeValue("FERelation", "subID")));
                            FrameElement superFE = superFrame.FrameElements.Get(int.Parse(relationP.AttributeValue("FERelation", "supID")));

                            subFE.AddSuperFrameElement(superFE, relation);
                            superFE.AddSubFrameElement(subFE, relation);
                        }
                    }
                }
                #endregion
            }
            else
            {
                throw new Exception("Unrecognized FrameNet version:  " + version);
            }
        }