Beispiel #1
0
        void ApplySimultaneous(PhoneticShape input, List <Subrule> subrules)
        {
            foreach (Subrule sr in subrules)
            {
                // first find all segments which match the LHS
                List <Match>      matches = new List <Match>();
                PhoneticShapeNode node    = input.First;
                Match             match;
                while (FindNextMatchLHS(node, Direction.RIGHT, out match))
                {
                    // check each candidate match against the subrule's environment
                    IList <PhoneticShapeNode> nodes            = match.EntireMatch;
                    VariableValues            instantiatedVars = match.VariableValues;
                    if (m_lhs.Count == 0
                                                ? sr.MatchEnvEmpty(nodes[0], Direction.RIGHT, ModeType.SYNTHESIS, instantiatedVars)
                                                : sr.MatchEnvNonempty(nodes, Direction.RIGHT, ModeType.SYNTHESIS, instantiatedVars))
                    {
                        matches.Add(match);
                        node = nodes[nodes.Count - 1].Next;
                    }
                    else
                    {
                        node = nodes[0].Next;
                    }
                }

                // then apply changes
                foreach (Match m in matches)
                {
                    sr.ApplyRHS(Direction.RIGHT, m.EntireMatch, m.VariableValues);
                }
            }
        }
Beispiel #2
0
 /// <summary>
 /// Searches for the lexical entry that matches the specified shape.
 /// </summary>
 /// <param name="shape">The shape.</param>
 /// <returns>The matching lexical entries.</returns>
 public IEnumerable <LexEntry.RootAllomorph> SearchEntries(PhoneticShape shape)
 {
     foreach (SegmentDefinitionTrie <LexEntry.RootAllomorph> .Match match in m_entryTrie.Search(shape))
     {
         yield return(match.Value);
     }
 }
Beispiel #3
0
        void ApplyIterative(PhoneticShape input, Direction dir, List <Subrule> subrules)
        {
            Match             match;
            PhoneticShapeNode node = input.GetFirst(dir);

            // iterate thru each LHS match
            while (FindNextMatchLHS(node, dir, out match))
            {
                IList <PhoneticShapeNode> nodes            = match.EntireMatch;
                VariableValues            instantiatedVars = match.VariableValues;
                bool matched = false;
                // check each subrule's environment
                foreach (Subrule sr in subrules)
                {
                    if (m_lhs.Count == 0
                                                ? sr.MatchEnvEmpty(nodes[0], dir, ModeType.SYNTHESIS, instantiatedVars)
                                                : sr.MatchEnvNonempty(nodes, dir, ModeType.SYNTHESIS, instantiatedVars))
                    {
                        sr.ApplyRHS(dir, nodes, instantiatedVars);
                        matched = true;
                        break;
                    }
                }

                if (matched)
                {
                    node = nodes[nodes.Count - 1].GetNext(dir);
                }
                else
                {
                    node = nodes[0].GetNext(dir);
                }
            }
        }
Beispiel #4
0
        void Untruncate(PhoneticPattern lhs, PhoneticShape output, bool optional, VariableValues instantiatedVars)
        {
            // create segments from the LHS partition pattern and append them to the output
            foreach (PhoneticPatternNode node in lhs)
            {
                switch (node.Type)
                {
                case PhoneticPatternNode.NodeType.SIMP_CTXT:
                    SimpleContext ctxt   = node as SimpleContext;
                    Segment       newSeg = ctxt.UnapplyDeletion(instantiatedVars);
                    newSeg.IsOptional = optional;
                    output.Add(newSeg);
                    break;

                case PhoneticPatternNode.NodeType.PATTERN:
                    NestedPhoneticPattern nestedPattern = node as NestedPhoneticPattern;
                    // untruncate nested partitions the maximum number of times it can occur,
                    // marking any segments that occur after the minimum number of occurrences
                    // as optional
                    for (int j = 0; j < nestedPattern.MaxOccur; j++)
                    {
                        Untruncate(nestedPattern.Pattern, output, j >= nestedPattern.MinOccur, instantiatedVars);
                    }
                    break;

                case PhoneticPatternNode.NodeType.BDRY_CTXT:
                    // skip boundaries
                    break;
                }
            }
        }
Beispiel #5
0
        /// <summary>
        /// Initializes a new instance of the <see cref="WordSynthesis"/> class.
        /// </summary>
        /// <param name="rootAllomorph">The root allomorph.</param>
        /// <param name="nonHead">The non-head synthesis.</param>
        /// <param name="rzFeatures">The realizational features.</param>
        /// <param name="mrules">The morphological rules to apply.</param>
        /// <param name="curTrace">The current trace record.</param>
        internal WordSynthesis(LexEntry.RootAllomorph rootAllomorph, WordSynthesis nonHead, FeatureValues rzFeatures, IEnumerable <MorphologicalRule> mrules,
                               Trace curTrace)
        {
            m_root        = (LexEntry)rootAllomorph.Morpheme;
            m_mprFeatures = m_root.MPRFeatures != null?m_root.MPRFeatures.Clone() : new MPRFeatureSet();

            m_headFeatures = m_root.HeadFeatures != null?m_root.HeadFeatures.Clone() : new FeatureValues();

            m_footFeatures = m_root.FootFeatures != null?m_root.FootFeatures.Clone() : new FeatureValues();

            m_pos     = m_root.POS;
            m_stratum = m_root.Stratum;

            m_nonHead = nonHead;
            m_morphs  = new Morphs();
            Morph morph = new Morph(rootAllomorph);

            morph.Shape.AddMany(rootAllomorph.Shape.Segments);
            m_morphs.Add(morph);
            m_shape = new PhoneticShape();
            m_shape.Add(new Margin(Direction.LEFT));
            m_shape.AddPartition(rootAllomorph.Shape.Segments, morph.Partition);
            m_shape.Add(new Margin(Direction.RIGHT));

            m_obligHeadFeatures = new HCObjectSet <Feature>();
            m_mrules            = new List <MorphologicalRule>(mrules);
            m_rzFeatures        = rzFeatures;
            m_curTrace          = curTrace;
            m_mrulesApplied     = new Dictionary <MorphologicalRule, int>();
        }
Beispiel #6
0
        /// <summary>
        /// Generates a string representation of the specified phonetic shape.
        /// </summary>
        /// <param name="shape">The phonetic shape.</param>
        /// <param name="mode">The mode.</param>
        /// <param name="includeBdry">if <c>true</c> boundary markers will be included in the
        /// string representation.</param>
        /// <returns>The string representation.</returns>
        public string ToString(PhoneticShape shape, ModeType mode, bool includeBdry)
        {
            StringBuilder sb = new StringBuilder();

            foreach (PhoneticShapeNode node in shape)
            {
                switch (node.Type)
                {
                case PhoneticShapeNode.NodeType.SEGMENT:
                    Segment seg = node as Segment;
                    IList <SegmentDefinition> segDefs = GetMatchingSegmentDefinitions(seg, mode);
                    if (segDefs.Count > 0)
                    {
                        sb.Append(segDefs[0].StrRep);
                    }
                    break;

                case PhoneticShapeNode.NodeType.BOUNDARY:
                    if (includeBdry)
                    {
                        Boundary bdry = node as Boundary;
                        sb.Append(bdry.BoundaryDefinition.StrRep);
                    }
                    break;
                }
            }
            return(sb.ToString());
        }
Beispiel #7
0
        /// <summary>
        /// Applies the rule to the specified word synthesis.
        /// </summary>
        /// <param name="input">The word synthesis.</param>
        public override void Apply(WordSynthesis input)
        {
            PhonologicalRuleSynthesisTrace trace = null;

            if (TraceSynthesis)
            {
                // create phonological rule synthesis trace record
                trace = new PhonologicalRuleSynthesisTrace(this, input.Clone());
                input.CurrentTrace.AddChild(trace);
            }

            // only try to apply applicable subrules
            List <Subrule> subrules = new List <Subrule>();

            foreach (Subrule sr in m_subrules)
            {
                if (sr.IsApplicable(input))
                {
                    subrules.Add(sr);
                }
            }

            if (subrules.Count > 0)
            {
                // set all segments to clean
                PhoneticShape pshape = input.Shape;
                foreach (PhoneticShapeNode node in pshape)
                {
                    if (node.Type == PhoneticShapeNode.NodeType.SEGMENT)
                    {
                        (node as Segment).IsClean = true;
                    }
                }

                switch (m_multApplication)
                {
                case MultAppOrder.SIMULTANEOUS:
                    ApplySimultaneous(input.Shape, subrules);
                    break;

                case MultAppOrder.LR_ITERATIVE:
                    ApplyIterative(input.Shape, Direction.RIGHT, subrules);
                    break;

                case MultAppOrder.RL_ITERATIVE:
                    ApplyIterative(input.Shape, Direction.LEFT, subrules);
                    break;
                }
            }

            // add output to phonological rule trace record
            if (trace != null)
            {
                trace.Output = input.Clone();
            }
        }
Beispiel #8
0
 /// <summary>
 /// Initializes a new instance of the <see cref="WordAnalysis"/> class.
 /// </summary>
 /// <param name="shape">The shape.</param>
 /// <param name="curTrace">The current trace record.</param>
 internal WordAnalysis(PhoneticShape shape, Stratum stratum, Trace curTrace)
 {
     m_shape           = shape;
     m_pos             = new HCObjectSet <PartOfSpeech>();
     m_mrules          = new List <MorphologicalRule>();
     m_mrulesUnapplied = new Dictionary <MorphologicalRule, int>();
     m_rzFeatures      = new FeatureValues();
     m_stratum         = stratum;
     m_curTrace        = curTrace;
 }
        /// <summary>
        /// Determines whether the specified word matches the specified phonetic shape.
        /// All unused IPA modifiers in the word are ignored when attempting to match
        /// the phonetic shape.
        /// </summary>
        /// <param name="word">The word.</param>
        /// <param name="shape">The phonetic shape.</param>
        /// <returns>
        ///     <c>true</c> if the word matches the shape, otherwise <c>false</c>.
        /// </returns>
        public override bool IsMatch(string word, PhoneticShape shape)
        {
            string tword;

            if (!StripUnusedChars(word, out tword))
            {
                return(false);
            }

            return(base.IsMatch(tword, shape));
        }
Beispiel #10
0
            PhoneticShape UnapplyRHS(Match match)
            {
                PhoneticShape output = new PhoneticShape();

                output.Add(new Margin(Direction.LEFT));
                // iterate thru LHS partitions, copying the matching partition from the
                // input to the output
                for (int i = 0; i < m_transform.PartitionCount; i++)
                {
                    m_transform.Unapply(match, i, output);
                }
                output.Add(new Margin(Direction.RIGHT));
                return(output);
            }
Beispiel #11
0
 /// <summary>
 /// Copy constructor.
 /// </summary>
 /// <param name="wa">The word analysis.</param>
 public WordAnalysis(WordAnalysis wa)
 {
     m_shape         = wa.m_shape.Clone();
     m_pos           = new HCObjectSet <PartOfSpeech>(wa.m_pos);
     m_rootAllomorph = wa.m_rootAllomorph;
     if (wa.m_nonHead != null)
     {
         m_nonHead = wa.m_nonHead.Clone();
     }
     m_mrules          = new List <MorphologicalRule>(wa.m_mrules);
     m_mrulesUnapplied = new Dictionary <MorphologicalRule, int>(wa.m_mrulesUnapplied);
     m_rzFeatures      = wa.m_rzFeatures.Clone();
     m_curTrace        = wa.m_curTrace;
     m_stratum         = wa.m_stratum;
 }
Beispiel #12
0
            /// <summary>
            /// Unapplies this subrule to the input word analysis.
            /// </summary>
            /// <param name="input">The input word analysis.</param>
            /// <param name="output">The output word analyses.</param>
            /// <returns><c>true</c> if the subrule was successfully unapplied, otherwise <c>false</c></returns>
            public bool Unapply(WordAnalysis input, out ICollection <WordAnalysis> output)
            {
                VariableValues instantiatedVars = new VariableValues(m_alphaVars);
                IList <Match>  matches;

                m_transform.RHSTemplate.IsMatch(input.Shape.First, Direction.RIGHT, ModeType.ANALYSIS, instantiatedVars, out matches);

                List <WordAnalysis> outputList = new List <WordAnalysis>();

                output = outputList;
                foreach (Match match in matches)
                {
                    PhoneticShape shape = UnapplyRHS(match);

                    if (shape.Count > 2)
                    {
                        // check to see if this is a duplicate of another output analysis, this is not strictly necessary, but
                        // it helps to reduce the search space
                        bool add = true;
                        for (int i = 0; i < output.Count; i++)
                        {
                            if (shape.Duplicates(outputList[i].Shape))
                            {
                                if (shape.Count > outputList[i].Shape.Count)
                                {
                                    // if this is a duplicate and it is longer, then use this analysis and remove the previous one
                                    outputList.RemoveAt(i);
                                }
                                else
                                {
                                    // if it is shorter, then do not add it to the output list
                                    add = false;
                                }
                                break;
                            }
                        }

                        if (add)
                        {
                            WordAnalysis wa = input.Clone();
                            wa.Shape = shape;
                            output.Add(wa);
                        }
                    }
                }

                return(outputList.Count > 0);
            }
Beispiel #13
0
 void UnapplyRHS(Match match, out PhoneticShape headShape, out PhoneticShape nonHeadShape)
 {
     headShape = new PhoneticShape();
     headShape.Add(new Margin(Direction.LEFT));
     nonHeadShape = new PhoneticShape();
     nonHeadShape.Add(new Margin(Direction.LEFT));
     // iterate thru LHS partitions, copying the matching partition from the
     // input to the output
     for (int i = 0; i < m_transform.PartitionCount; i++)
     {
         PhoneticShape curShape = i < m_firstNonHeadPartition ? headShape : nonHeadShape;
         m_transform.Unapply(match, i, curShape);
     }
     headShape.Add(new Margin(Direction.RIGHT));
     nonHeadShape.Add(new Margin(Direction.RIGHT));
 }
Beispiel #14
0
            /// <summary>
            /// Unapplies this subrule to specified input phonetic shape.
            /// </summary>
            /// <param name="input">The input phonetic shape.</param>
            public void Unapply(PhoneticShape input)
            {
                if (Type == ChangeType.NARROW)
                {
                    int i = 0;
                    // because deletion rules are self-opaquing it is unclear how many segments
                    // could have been deleted during synthesis, so we unapply deletion rules
                    // multiple times. Unfortunately, this could create a situation where the
                    // deletion rule is unapplied infinitely, so we put an upper limit on the
                    // number of times a deletion rule can unapply.
                    while (i <= m_rule.Morpher.DelReapplications && UnapplyNarrow(input))
                    {
                        i++;
                    }
                }
                else
                {
                    Direction dir = Direction.LEFT;
                    switch (m_rule.m_multApplication)
                    {
                    case MultAppOrder.LR_ITERATIVE:
                    case MultAppOrder.SIMULTANEOUS:
                        // simultaneous subrules could be unapplied left-to-right or
                        // right-to-left, we arbitrarily choose left-to-right
                        dir = Direction.LEFT;
                        break;

                    case MultAppOrder.RL_ITERATIVE:
                        dir = Direction.RIGHT;
                        break;
                    }

                    // only simultaneous subrules can be self-opaquing
                    if (IsSelfOpaquing)
                    {
                        // unapply the subrule until it no longer makes a change
                        while (UnapplyIterative(input, dir))
                        {
                        }
                    }
                    else
                    {
                        UnapplyIterative(input, dir);
                    }
                }
            }
Beispiel #15
0
            bool UnapplyIterative(PhoneticShape input, Direction dir)
            {
                bool unapplied         = false;
                PhoneticShapeNode node = input.GetFirst(dir);
                Match             match;

                // iterate thru all matches
                while (FindNextMatchRHS(node, dir, out match))
                {
                    // unapply the subrule
                    IList <PhoneticShapeNode> nodes = match.EntireMatch;
                    UnapplyRHS(dir, nodes, match.VariableValues);
                    unapplied = true;
                    node      = nodes[nodes.Count - 1].GetNext(dir);
                }

                return(unapplied);
            }
Beispiel #16
0
        bool ProcessIterative(PhoneticShape input, Direction dir, PhoneticPattern ptemp, ModeType mode)
        {
            bool reordered         = false;
            PhoneticShapeNode node = input.GetFirst(dir);
            Match             match;

            // iterate thru each match
            while (FindNextMatch(node, dir, ptemp, mode, out match))
            {
                // reorder the matching segments
                Reorder(dir, match);
                reordered = true;
                IList <PhoneticShapeNode> nodes = match.EntireMatch;
                node = nodes[nodes.Count - 1].GetNext(dir);
            }

            return(reordered);
        }
Beispiel #17
0
            bool UnapplyNarrow(PhoneticShape input)
            {
                List <Match>      matches = new List <Match>();
                PhoneticShapeNode node    = input.First;
                Match             match;

                // deletion subrules are always treated like simultaneous subrules during unapplication
                while (FindNextMatchRHS(node, Direction.RIGHT, out match))
                {
                    matches.Add(match);
                    node = match.EntireMatch[0].Next;
                }

                foreach (Match m in matches)
                {
                    PhoneticShapeNode cur = m.EntireMatch[m.EntireMatch.Count - 1];
                    foreach (PhoneticPatternNode lhsNode in m_rule.m_lhs)
                    {
                        if (lhsNode.Type != PhoneticPatternNode.NodeType.SIMP_CTXT)
                        {
                            continue;
                        }

                        SimpleContext ctxt   = lhsNode as SimpleContext;
                        Segment       newSeg = ctxt.UnapplyDeletion(m.VariableValues);
                        // mark the undeleted segment as optional
                        newSeg.IsOptional = true;
                        cur.Insert(newSeg, Direction.RIGHT);
                        cur = newSeg;
                    }

                    if (m_analysisTarget.Count > 0)
                    {
                        foreach (PhoneticShapeNode matchNode in m.EntireMatch)
                        {
                            matchNode.IsOptional = true;
                        }
                    }
                }

                return(matches.Count > 0);
            }
Beispiel #18
0
 /// <summary>
 /// Copy constructor.
 /// </summary>
 /// <param name="ws">The word synthesis.</param>
 public WordSynthesis(WordSynthesis ws)
 {
     m_root = ws.m_root;
     if (ws.m_nonHead != null)
     {
         m_nonHead = ws.m_nonHead.Clone();
     }
     m_shape             = ws.m_shape.Clone();
     m_morphs            = ws.m_morphs.Clone();
     m_pos               = ws.m_pos;
     m_mprFeatures       = ws.m_mprFeatures.Clone();
     m_headFeatures      = ws.m_headFeatures.Clone();
     m_footFeatures      = ws.m_footFeatures.Clone();
     m_obligHeadFeatures = new HCObjectSet <Feature>(ws.m_obligHeadFeatures);
     m_mrules            = new List <MorphologicalRule>(ws.m_mrules);
     m_curRuleIndex      = ws.m_curRuleIndex;
     m_rzFeatures        = ws.m_rzFeatures.Clone();
     m_curTrace          = ws.m_curTrace;
     m_stratum           = ws.m_stratum;
     m_mrulesApplied     = new Dictionary <MorphologicalRule, int>(ws.m_mrulesApplied);
 }
Beispiel #19
0
        /// <summary>
        /// Converts the specified string to a phonetic shape. It matches the longest possible segment
        /// first.
        /// </summary>
        /// <param name="str">The string.</param>
        /// <param name="mode">The mode.</param>
        /// <returns>The phonetic shape, <c>null</c> if the string contains invalid segments.</returns>
        public PhoneticShape ToPhoneticShape(string str, ModeType mode)
        {
            PhoneticShape ps = new PhoneticShape();
            int           i  = 0;

            ps.Add(new Margin(Direction.LEFT));
            while (i < str.Length)
            {
                bool match = false;
                for (int j = str.Length - i; j > 0; j--)
                {
                    string            s    = str.Substring(i, j);
                    PhoneticShapeNode node = GetPhoneticShapeNode(s, mode);
                    if (node != null)
                    {
                        try
                        {
                            ps.Add(node);
                        }
                        catch (InvalidOperationException)
                        {
                            return(null);
                        }
                        i    += j;
                        match = true;
                        break;
                    }
                }

                if (!match)
                {
                    return(null);
                }
            }
            ps.Add(new Margin(Direction.RIGHT));

            return(ps);
        }
Beispiel #20
0
        /// <summary>
        /// Unapplies this transform to the specified partition in the specified match.
        /// </summary>
        /// <param name="match">The match.</param>
        /// <param name="partition">The partition.</param>
        /// <param name="output">The output.</param>
        public void Unapply(Match match, int partition, PhoneticShape output)
        {
            IList <PhoneticShapeNode> nodes = match.GetPartition(partition);

            if (nodes != null && nodes.Count > 0)
            {
                SimpleContext ctxt;
                if (!m_modifyFromCtxts.TryGetValue(partition, out ctxt))
                {
                    ctxt = null;
                }

                foreach (PhoneticShapeNode node in nodes)
                {
                    switch (node.Type)
                    {
                    case PhoneticShapeNode.NodeType.SEGMENT:
                        Segment newSeg = new Segment(node as Segment);
                        // if there is a modify-from context on this partition, unapply it
                        if (ctxt != null)
                        {
                            ctxt.Unapply(newSeg, match.VariableValues);
                        }
                        output.Add(newSeg);
                        break;

                    case PhoneticShapeNode.NodeType.BOUNDARY:
                        output.Add(node.Clone());
                        break;
                    }
                }
            }
            else
            {
                // untruncate a partition
                Untruncate(m_lhs[partition], output, false, match.VariableValues);
            }
        }
Beispiel #21
0
 /// <summary>
 /// Initializes a new instance of the <see cref="RootTrace"/> class.
 /// </summary>
 /// <param name="inputWord">The input word.</param>
 /// <param name="inputShape">The input shape.</param>
 internal WordAnalysisTrace(string inputWord, PhoneticShape inputShape)
 {
     m_inputWord  = inputWord;
     m_inputShape = inputShape;
 }
Beispiel #22
0
 /// <summary>
 /// Copy constructor.
 /// </summary>
 /// <param name="morph">The morph.</param>
 public Morph(Morph morph)
 {
     m_partition = morph.m_partition;
     m_shape     = morph.m_shape.Clone();
     m_allomorph = morph.m_allomorph;
 }
Beispiel #23
0
 /// <summary>
 /// Initializes a new instance of the <see cref="Morph"/> class.
 /// </summary>
 /// <param name="allomorph">The allomorph.</param>
 public Morph(Allomorph allomorph)
 {
     m_allomorph = allomorph;
     m_shape     = new PhoneticShape();
 }
Beispiel #24
0
 /// <summary>
 /// Initializes a new instance of the <see cref="InsertSegments"/> class.
 /// </summary>
 /// <param name="pshape">The phonetic shape.</param>
 public InsertSegments(PhoneticShape pshape)
 {
     m_pshape = pshape;
 }
Beispiel #25
0
        /// <summary>
        /// Converts the specified phonetic shape to a valid regular expression string. Regular expressions
        /// formatted for display purposes are NOT guaranteed to compile.
        /// </summary>
        /// <param name="shape">The phonetic shape.</param>
        /// <param name="mode">The mode.</param>
        /// <param name="displayFormat">if <c>true</c> the result will be formatted for display, otherwise
        /// it will be formatted for compilation.</param>
        /// <returns>The regular expression string.</returns>
        public string ToRegexString(PhoneticShape shape, ModeType mode, bool displayFormat)
        {
            StringBuilder sb = new StringBuilder();

            foreach (PhoneticShapeNode node in shape)
            {
                switch (node.Type)
                {
                case PhoneticShapeNode.NodeType.SEGMENT:
                    Segment seg = node as Segment;
                    IList <SegmentDefinition> segDefs = GetMatchingSegmentDefinitions(seg, mode);
                    if (segDefs.Count > 0)
                    {
                        if (segDefs.Count > 1)
                        {
                            sb.Append(displayFormat ? "[" : "(");
                        }
                        for (int i = 0; i < segDefs.Count; i++)
                        {
                            if (segDefs[i].StrRep.Length > 1)
                            {
                                sb.Append("(");
                            }

                            if (displayFormat)
                            {
                                sb.Append(segDefs[i].StrRep);
                            }
                            else
                            {
                                sb.Append(Regex.Escape(segDefs[i].StrRep));
                            }

                            if (segDefs[i].StrRep.Length > 1)
                            {
                                sb.Append(")");
                            }
                            if (i < segDefs.Count - 1 && !displayFormat)
                            {
                                sb.Append("|");
                            }
                        }
                        if (segDefs.Count > 1)
                        {
                            sb.Append(displayFormat ? "]" : ")");
                        }

                        if (seg.IsOptional)
                        {
                            sb.Append("?");
                        }
                    }
                    break;

                case PhoneticShapeNode.NodeType.BOUNDARY:
                    Boundary bdry = node as Boundary;
                    if (bdry.BoundaryDefinition.StrRep.Length > 1)
                    {
                        sb.Append("(");
                    }

                    if (displayFormat)
                    {
                        sb.Append(bdry.BoundaryDefinition.StrRep);
                    }
                    else
                    {
                        sb.Append(Regex.Escape(bdry.BoundaryDefinition.StrRep));
                    }

                    if (bdry.BoundaryDefinition.StrRep.Length > 1)
                    {
                        sb.Append(")");
                    }
                    sb.Append("?");
                    break;

                case PhoneticShapeNode.NodeType.MARGIN:
                    if (!displayFormat)
                    {
                        Margin margin = node as Margin;
                        sb.Append(margin.MarginType == Direction.LEFT ? "^" : "$");
                    }
                    break;
                }
            }
            return(sb.ToString());
        }
Beispiel #26
0
 /// <summary>
 /// Initializes a new instance of the <see cref="LexLookupTrace"/> class.
 /// </summary>
 /// <param name="stratum">The stratum.</param>
 /// <param name="shape">The shape.</param>
 internal LexLookupTrace(Stratum stratum, PhoneticShape shape)
 {
     m_stratum = stratum;
     m_shape   = shape;
 }
Beispiel #27
0
 public IEnumerable <Match> SearchPartial(PhoneticShape shape)
 {
     return(new Set <Match>(m_root.Search(shape.GetFirst(m_dir), m_dir, true)));
 }
Beispiel #28
0
 /// <summary>
 /// Adds the specified lexical entry.
 /// </summary>
 /// <param name="entry">The lexical entry.</param>
 public void Add(PhoneticShape shape, T value)
 {
     m_root.Add(shape.GetFirst(m_dir), value, m_dir);
     m_numValues++;
 }
Beispiel #29
0
        /// <summary>
        /// Does the real work of morphing the specified word.
        /// </summary>
        /// <param name="word">The word.</param>
        /// <param name="prev">The previous word.</param>
        /// <param name="next">The next word.</param>
        /// <param name="trace">The trace.</param>
        /// <returns>All valid word synthesis records.</returns>
        ICollection <WordSynthesis> MorphAndLookupToken(string word, string prev, string next, out WordAnalysisTrace trace, string[] selectTraceMorphs)
        {
            // convert the word to its phonetic shape
            PhoneticShape input = SurfaceStratum.CharacterDefinitionTable.ToPhoneticShape(word, ModeType.ANALYSIS);

            // if word contains invalid segments, the char def table will return null
            if (input == null)
            {
                MorphException me = new MorphException(MorphException.MorphErrorType.INVALID_SHAPE, this,
                                                       string.Format(HCStrings.kstidInvalidWord, word, SurfaceStratum.CharacterDefinitionTable.ID));
                me.Data["shape"]        = word;
                me.Data["charDefTable"] = SurfaceStratum.CharacterDefinitionTable.ID;
                throw me;
            }

            // create the root of the trace tree
            trace = new WordAnalysisTrace(word, input.Clone());

            Set <WordSynthesis> candidates  = new Set <WordSynthesis>();
            Set <WordAnalysis>  inAnalysis  = new Set <WordAnalysis>();
            Set <WordAnalysis>  outAnalysis = new Set <WordAnalysis>();

            inAnalysis.Add(new WordAnalysis(input, SurfaceStratum, trace));

            // Unapply rules
            for (int i = m_strata.Count - 1; i >= 0; i--)
            {
                outAnalysis.Clear();
                foreach (WordAnalysis wa in inAnalysis)
                {
                    if (m_traceStrataAnalysis)
                    {
                        // create the stratum analysis input trace record
                        StratumAnalysisTrace stratumTrace = new StratumAnalysisTrace(m_strata[i], true, wa.Clone());
                        wa.CurrentTrace.AddChild(stratumTrace);
                    }
                    foreach (WordAnalysis outWa in m_strata[i].Unapply(wa, candidates, selectTraceMorphs))
                    {
                        // promote each analysis to the next stratum
                        if (i != 0)
                        {
                            outWa.Stratum = m_strata[i - 1];
                        }

                        if (m_traceStrataAnalysis)
                        {
                            // create the stratum analysis output trace record for the output word synthesis
                            outWa.CurrentTrace.AddChild(new StratumAnalysisTrace(m_strata[i], false, outWa.Clone()));
                        }

                        outAnalysis.Add(outWa);
                    }
                }

                inAnalysis.Clear();
                inAnalysis.AddMany(outAnalysis);
            }

            Set <WordSynthesis> allValidSyntheses = new Set <WordSynthesis>();

            // Apply rules for each candidate entry
            foreach (WordSynthesis candidate in candidates)
            {
                Set <WordSynthesis> inSynthesis  = new Set <WordSynthesis>();
                Set <WordSynthesis> outSynthesis = new Set <WordSynthesis>();
                for (int i = 0; i < m_strata.Count; i++)
                {
                    // start applying at the stratum that this lex entry belongs to
                    if (m_strata[i] == candidate.Root.Stratum)
                    {
                        inSynthesis.Add(candidate);
                    }

                    outSynthesis.Clear();
                    foreach (WordSynthesis cur in inSynthesis)
                    {
                        if (m_traceStrataSynthesis)
                        {
                            // create the stratum synthesis input trace record
                            StratumSynthesisTrace stratumTrace = new StratumSynthesisTrace(m_strata[i], true, cur.Clone());
                            cur.CurrentTrace.AddChild(stratumTrace);
                        }
                        foreach (WordSynthesis outWs in m_strata[i].Apply(cur))
                        {
                            // promote the word synthesis to the next stratum
                            if (i != m_strata.Count - 1)
                            {
                                outWs.Stratum = m_strata[i + 1];
                            }

                            if (m_traceStrataSynthesis)
                            {
                                // create the stratum synthesis output trace record for the output analysis
                                outWs.CurrentTrace.AddChild(new StratumSynthesisTrace(m_strata[i], false, outWs.Clone()));
                            }

                            outSynthesis.Add(outWs);
                        }
                    }

                    inSynthesis.Clear();
                    inSynthesis.AddMany(outSynthesis);
                }

                foreach (WordSynthesis ws in outSynthesis)
                {
                    if (ws.IsValid)
                    {
                        allValidSyntheses.Add(ws);
                    }
                }
            }

            Set <WordSynthesis> results = new Set <WordSynthesis>();
            // sort the resulting syntheses according to the order of precedence of each allomorph in
            // their respective morphemes
            List <WordSynthesis> sortedSyntheses = new List <WordSynthesis>(allValidSyntheses);

            sortedSyntheses.Sort();

            WordSynthesis prevValidSynthesis = null;

            foreach (WordSynthesis cur in sortedSyntheses)
            {
                // enforce the disjunctive property of allomorphs by ensuring that this word synthesis
                // has the highest order of precedence for its allomorphs while also allowing for free
                // fluctuation, also check that the phonetic shape matches the original input word
                if ((prevValidSynthesis == null || AreAllomorphsNondisjunctive(cur, prevValidSynthesis)) &&
                    SurfaceStratum.CharacterDefinitionTable.IsMatch(word, cur.Shape))
                {
                    if (m_traceSuccess)
                    {
                        // create the report a success output trace record for the output analysis
                        cur.CurrentTrace.AddChild(new ReportSuccessTrace(cur));
                    }
                    // do not add to the result if it has the same root, shape, and morphemes as another result
                    bool duplicate = false;
                    foreach (WordSynthesis ws in results)
                    {
                        if (cur.Duplicates(ws))
                        {
                            duplicate = true;
                            break;
                        }
                    }
                    if (!duplicate)
                    {
                        results.Add(cur);
                    }
                }
                prevValidSynthesis = cur;
            }
            return(results);
        }
Beispiel #30
0
        /// <summary>
        /// Determines whether the specified word matches the specified phonetic shape.
        /// </summary>
        /// <param name="word">The word.</param>
        /// <param name="shape">The phonetic shape.</param>
        /// <returns>
        ///     <c>true</c> if the word matches the shape, otherwise <c>false</c>.
        /// </returns>
        public virtual bool IsMatch(string word, PhoneticShape shape)
        {
            string pattern = ToRegexString(shape, ModeType.SYNTHESIS, false);

            return(Regex.IsMatch(word, pattern, RegexOptions.IgnoreCase | RegexOptions.CultureInvariant));
        }