예제 #1
0
        void ApplyMorphologicalRules(WordSynthesis input, int rIndex, Set <WordSynthesis> output)
        {
            // iterate thru all rules starting from the specified rule in synthesis order
            for (int i = rIndex; i < m_mrules.Count; i++)
            {
                if (m_mrules[i].IsApplicable(input))
                {
                    ICollection <WordSynthesis> syntheses;
                    if (m_mrules[i].Apply(input, out syntheses))
                    {
                        foreach (WordSynthesis ws in syntheses)
                        {
                            // recursive call so that we can cover every permutation of rule application
                            switch (m_mruleOrder)
                            {
                            case MRuleOrder.LINEAR:
                                ApplyMorphologicalRules(ws, i, output);
                                break;

                            case MRuleOrder.UNORDERED:
                                ApplyMorphologicalRules(ws, 0, output);
                                break;
                            }
                        }
                    }
                }
            }

            ApplyTemplates(input, output);
        }
예제 #2
0
 void ApplyPhonologicalRules(WordSynthesis input)
 {
     for (int i = 0; i < m_prules.Count; i++)
     {
         m_prules[i].Apply(input);
     }
 }
예제 #3
0
        /// <summary>
        /// If the list of Realizational Features is non-empty, choose from either the input stem or its relatives
        /// of this stratum that stem which incorporates the most realizational features (without being incompatible
        /// with any realizational feature or with the head and foot features of the input stem).
        /// </summary>
        /// <param name="ws">The input word synthesis.</param>
        /// <returns>The resulting word synthesis.</returns>
        WordSynthesis ChooseInflStem(WordSynthesis ws)
        {
            if (ws.RealizationalFeatures.NumFeatures == 0 || ws.Root.Family == null)
            {
                return(ws);
            }

            WordSynthesis best = ws;

            // iterate thru all relatives
            foreach (LexEntry relative in ws.Root.Family.Entries)
            {
                if (relative != ws.Root && relative.Stratum == ws.Stratum &&
                    ws.RealizationalFeatures.IsCompatible(relative.HeadFeatures) &&
                    ws.POS == relative.POS && relative.FootFeatures.Equals(ws.FootFeatures))
                {
                    FeatureValues remainder;
                    if (best.HeadFeatures.GetSupersetRemainder(relative.HeadFeatures, out remainder) && remainder.NumFeatures > 0 &&
                        ws.RealizationalFeatures.IsCompatible(remainder))
                    {
                        if (Morpher.TraceBlocking)
                        {
                            // create blocking trace record, should this become the current trace?
                            ws.CurrentTrace.AddChild(new BlockingTrace(BlockingTrace.BlockType.TEMPLATE, relative));
                        }
                        best = new WordSynthesis(relative.PrimaryAllomorph, ws.RealizationalFeatures, ws.CurrentTrace);
                    }
                }
            }
            return(best);
        }
예제 #4
0
        /// <summary>
        /// Applies the simple context to the input partition and copies it over to the output
        /// phonetic shape.
        /// </summary>
        /// <param name="match">The match.</param>
        /// <param name="input">The input word synthesis.</param>
        /// <param name="output">The output word synthesis.</param>
        /// <param name="morpheme">The morpheme info.</param>
        public override void Apply(Match match, WordSynthesis input, WordSynthesis output, Allomorph allomorph)
        {
            IList <PhoneticShapeNode> nodes = match.GetPartition(m_partition);

            if (nodes != null && nodes.Count > 0)
            {
                Morph morph = null;
                if (allomorph != null)
                {
                    morph = new Morph(allomorph);
                    output.Morphs.Add(morph);
                }
                for (PhoneticShapeNode node = nodes[0]; node != nodes[nodes.Count - 1].Next; node = node.Next)
                {
                    PhoneticShapeNode newNode = node.Clone();
                    if (node.Type == PhoneticShapeNode.NodeType.SEGMENT)
                    {
                        Segment seg = newNode as Segment;
                        // sets the context's features on the segment
                        m_ctxt.Apply(seg, match.VariableValues);
                        seg.IsClean   = false;
                        seg.Partition = morph == null ? -1 : morph.Partition;
                    }
                    if (morph != null)
                    {
                        morph.Shape.Add(newNode.Clone());
                    }
                    output.Shape.Add(newNode);
                }
            }
        }
        protected WordSynthesis CheckBlocking(WordSynthesis ws)
        {
            if (!m_isBlockable || ws.Root.Family == null)
            {
                return(ws);
            }

            // check all relatives
            foreach (LexEntry entry in ws.Root.Family.Entries)
            {
                // a relative will block if the part of speech, stratum, head features, and foot features match
                if (entry != ws.Root && ws.POS == entry.POS && entry.Stratum == ws.Stratum &&
                    entry.HeadFeatures.Equals(ws.HeadFeatures) &&
                    entry.FootFeatures.Equals(ws.FootFeatures))
                {
                    if (Morpher.TraceBlocking)
                    {
                        // create a blocking trace record, should this become the current trace?
                        ws.CurrentTrace.AddChild(new BlockingTrace(BlockingTrace.BlockType.RULE, entry));
                    }
                    return(new WordSynthesis(entry.PrimaryAllomorph, ws.RealizationalFeatures, ws.CurrentTrace));
                }
            }

            return(ws);
        }
예제 #6
0
 /// <summary>
 /// Determines whether this subrule is applicable to the specified word analysis.
 /// </summary>
 /// <param name="input">The word analysis.</param>
 /// <returns>
 ///     <c>true</c> if this subrule is applicable, otherwise <c>false</c>.
 /// </returns>
 public bool IsApplicable(WordSynthesis input)
 {
     // check part of speech and MPR features
     return((m_requiredPOSs == null || m_requiredPOSs.Count == 0 || m_requiredPOSs.Contains(input.POS)) &&
            (m_requiredMPRFeatures == null || m_requiredMPRFeatures.Count == 0 || m_requiredMPRFeatures.IsMatch(input.MPRFeatures)) &&
            (m_excludedMPRFeatures == null || m_excludedMPRFeatures.Count == 0 || !m_excludedMPRFeatures.IsMatch(input.MPRFeatures)));
 }
예제 #7
0
            /// <summary>
            /// Applies this subrule to the specified word synthesis.
            /// </summary>
            /// <param name="input">The input word synthesis.</param>
            /// <param name="output">The output word synthesis.</param>
            /// <returns><c>true</c> if the subrule was successfully applied, otherwise <c>false</c></returns>
            public bool Apply(WordSynthesis input, out WordSynthesis output)
            {
                output = null;

                // check MPR features
                if ((m_requiredMPRFeatures != null && m_requiredMPRFeatures.Count > 0 && !m_requiredMPRFeatures.IsMatch(input.MPRFeatures)) ||
                    (m_excludedMPRFeatures != null && m_excludedMPRFeatures.Count > 0 && m_excludedMPRFeatures.IsMatch(input.MPRFeatures)))
                {
                    return(false);
                }

                VariableValues instantiatedVars = new VariableValues(m_alphaVars);
                IList <Match>  headMatches, nonHeadMatches;

                if (m_headLhsTemp.IsMatch(input.Shape.First, Direction.RIGHT, ModeType.SYNTHESIS, instantiatedVars, out headMatches) &&
                    m_nonHeadLhsTemp.IsMatch(input.NonHead.Shape.First, Direction.RIGHT, ModeType.SYNTHESIS, instantiatedVars, out nonHeadMatches))
                {
                    output = input.Clone();
                    ApplyRHS(headMatches[0], nonHeadMatches[0], input, output);

                    if (m_outputMPRFeatures != null)
                    {
                        output.MPRFeatures.AddOutput(m_outputMPRFeatures);
                    }
                    return(true);
                }

                return(false);
            }
예제 #8
0
        /// <summary>
        /// Determines if the allomorphs in the two syntheses are not disjunctive.
        /// </summary>
        /// <param name="synthesis1">The first synthesis.</param>
        /// <param name="synthesis2">The second synthesis.</param>
        /// <returns></returns>
        private bool AreAllomorphsNondisjunctive(WordSynthesis synthesis1, WordSynthesis synthesis2)
        {
            if (synthesis1.Morphs.Count != synthesis2.Morphs.Count)
            {
                return(true);
            }

            IEnumerator <Morph> enum1 = synthesis1.Morphs.GetEnumerator();
            IEnumerator <Morph> enum2 = synthesis2.Morphs.GetEnumerator();

            while (enum1.MoveNext() && enum2.MoveNext())
            {
                // if they have different morphemes then these allomorphs are not disjunctive
                if (enum1.Current.Allomorph.Morpheme != enum2.Current.Allomorph.Morpheme)
                {
                    return(true);
                }

                // morphemes are the same, so check if they have the same constraints,
                // if they do then these allomorphs are not disjunctive
                if (enum1.Current.Allomorph.ConstraintsEqual(enum2.Current.Allomorph))
                {
                    return(true);
                }
            }
            return(false);
        }
예제 #9
0
        bool ApplyTemplates(WordSynthesis input, Set <WordSynthesis> output)
        {
            // if this word synthesis is not compatible with the realizational features,
            // then skip it
            if (!input.RealizationalFeatures.IsCompatible(input.HeadFeatures))
            {
                return(false);
            }

            WordSynthesis ws = ChooseInflStem(input);
            bool          applicableTemplate = false;

            foreach (AffixTemplate template in m_templates)
            {
                // HC.NET does not treat templates as applying disjunctively, as opposed to legacy HC,
                // which does
                if (template.IsApplicable(ws))
                {
                    applicableTemplate = true;
                    IEnumerable <WordSynthesis> tempOutput;
                    if (template.Apply(ws, out tempOutput))
                    {
                        output.AddMany(tempOutput);
                    }
                }
            }

            if (!applicableTemplate)
            {
                output.Add(ws);
            }

            return(applicableTemplate);
        }
            /// <summary>
            /// Determines whether this subrule is applicable to the specified word analysis.
            /// </summary>
            /// <param name="input">The word analysis.</param>
            /// <param name="trace"> </param>
            /// <returns>
            ///     <c>true</c> if this subrule is applicable, otherwise <c>false</c>.
            /// </returns>
            public bool IsApplicable(WordSynthesis input, Trace trace)
            {
                // check part of speech and MPR features
                bool fRequiredPOSMet         = m_requiredPOSs == null || m_requiredPOSs.Count == 0 || m_requiredPOSs.Contains(input.POS);
                bool fRequiredMPRFeaturesMet = m_requiredMPRFeatures == null || m_requiredMPRFeatures.Count == 0 || m_requiredMPRFeatures.IsMatch(input.MPRFeatures);
                bool fExcludedMPRFeaturesMet = m_excludedMPRFeatures == null || m_excludedMPRFeatures.Count == 0 || !m_excludedMPRFeatures.IsMatch(input.MPRFeatures);

                if (trace != null)
                {
                    if (!fRequiredPOSMet)
                    {
                        var badPosTrace = new PhonologicalRuleSynthesisRequiredPOSTrace(input.POS, m_requiredPOSs);
                        trace.AddChild(badPosTrace);
                    }
                    if (!fRequiredMPRFeaturesMet)
                    {
                        var badRequiredMPRFeaturesTrace =
                            new PhonologicalRuleSynthesisMPRFeaturesTrace(
                                PhonologicalRuleSynthesisMPRFeaturesTrace.PhonologicalRuleSynthesisMPRFeaturesTraceType.REQUIRED,
                                input.MPRFeatures, m_requiredMPRFeatures);
                        trace.AddChild(badRequiredMPRFeaturesTrace);
                    }
                    if (!fExcludedMPRFeaturesMet)
                    {
                        var badExcludedMPRFeaturesTrace =
                            new PhonologicalRuleSynthesisMPRFeaturesTrace(
                                PhonologicalRuleSynthesisMPRFeaturesTrace.PhonologicalRuleSynthesisMPRFeaturesTraceType.EXCLUDED,
                                input.MPRFeatures, m_excludedMPRFeatures);
                        trace.AddChild(badExcludedMPRFeaturesTrace);
                    }
                }
                return(fRequiredPOSMet && fRequiredMPRFeaturesMet && fExcludedMPRFeaturesMet);
            }
예제 #11
0
        /// <summary>
        /// Determines whether this rule is applicable to the specified word synthesis.
        /// </summary>
        /// <param name="input">The input word synthesis.</param>
        /// <returns>
        ///     <c>true</c> if the rule is applicable, otherwise <c>false</c>.
        /// </returns>
        public override bool IsApplicable(WordSynthesis input)
        {
            // TODO: check subcats.

            // check required parts of speech
            return(input.NextRule == this && input.GetNumAppliesForMorphologicalRule(this) < m_maxNumApps &&
                   (m_requiredPOSs == null || m_requiredPOSs.Count == 0 || m_requiredPOSs.Contains(input.POS)));
        }
예제 #12
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();
            }
        }
예제 #13
0
        public override bool ApplySlotAffix(WordSynthesis input, FeatureValues origHeadFeatures, out ICollection <WordSynthesis> output)
        {
            output = null;
            if (IsBlockedSlotAffix(origHeadFeatures))
            {
                return(false);
            }

            return(base.ApplySlotAffix(input, origHeadFeatures, out output));
        }
예제 #14
0
 void ApplyRHS(Match match, WordSynthesis input, WordSynthesis output)
 {
     output.Shape.Clear();
     output.Morphs.Clear();
     output.Shape.Add(new Margin(Direction.LEFT));
     foreach (MorphologicalOutput outputMember in m_transform.RHS)
     {
         outputMember.Apply(match, input, output, this);
     }
     output.Shape.Add(new Margin(Direction.RIGHT));
 }
예제 #15
0
        void PrettyPrintWordSynthesis(WordSynthesis ws)
        {
            StringBuilder sb = new StringBuilder();

            sb.Append("ID: ");
            sb.AppendLine(ws.Root.ID);
            sb.Append("POS: ");
            sb.AppendLine(ws.POS.Description);

            sb.Append("Morphs: ");
            bool firstItem = true;

            foreach (Morph morph in ws.Morphs)
            {
                string gl       = morph.Allomorph.Morpheme.Gloss == null ? "?" : morph.Allomorph.Morpheme.Gloss.Description;
                string shapeStr = ws.Stratum.CharacterDefinitionTable.ToString(morph.Shape, ModeType.SYNTHESIS, false);
                int    len      = Math.Max(shapeStr.Length, gl.Length);
                if (len > 0)
                {
                    if (!firstItem)
                    {
                        sb.Append(' ');
                    }
                    sb.Append(shapeStr.PadRight(len));
                    firstItem = false;
                }
            }
            sb.AppendLine();
            sb.Append("Gloss:  ");
            firstItem = true;
            foreach (Morph morph in ws.Morphs)
            {
                string gl       = morph.Allomorph.Morpheme.Gloss == null ? "?" : morph.Allomorph.Morpheme.Gloss.Description;
                string shapeStr = ws.Stratum.CharacterDefinitionTable.ToString(morph.Shape, ModeType.SYNTHESIS, false);
                int    len      = Math.Max(shapeStr.Length, gl.Length);
                if (len > 0)
                {
                    if (!firstItem)
                    {
                        sb.Append(' ');
                    }
                    sb.Append(gl.PadRight(len));
                    firstItem = false;
                }
            }
            sb.AppendLine();
            sb.Append("MPR Features: ");
            sb.AppendLine(ws.MPRFeatures.ToString());
            sb.Append("Head Features: ");
            sb.AppendLine(ws.HeadFeatures.ToString());
            sb.Append("Foot Features: ");
            sb.Append(ws.FootFeatures.ToString());
            m_out.WriteLine(sb.ToString());
        }
예제 #16
0
 public virtual void Write(WordSynthesis ws, bool prettyPrint)
 {
     if (prettyPrint)
     {
         PrettyPrintWordSynthesis(ws);
     }
     else
     {
         m_out.WriteLine(ws.ToString());
     }
     m_out.WriteLine();
 }
예제 #17
0
        /// <summary>
        /// Inserts a segment based on a simple context to the output.
        /// </summary>
        /// <param name="match">The match.</param>
        /// <param name="input">The input word synthesis.</param>
        /// <param name="output">The output word synthesis.</param>
        /// <param name="morpheme">The morpheme info.</param>
        public override void Apply(Match match, WordSynthesis input, WordSynthesis output, Allomorph allomorph)
        {
            Segment newSeg = m_ctxt.ApplyInsertion(match.VariableValues);

            if (allomorph != null)
            {
                Morph morph = new Morph(allomorph);
                output.Morphs.Add(morph);
                morph.Shape.Add(newSeg.Clone());
                newSeg.Partition = morph.Partition;
            }
            output.Shape.Add(newSeg);
        }
예제 #18
0
        public virtual void Write(WordSynthesis ws, bool prettyPrint)
        {
            m_xmlWriter.WriteStartElement("Result");
            Write("Root", ws.Root);
            m_xmlWriter.WriteElementString("POS", ws.POS.Description);

            m_xmlWriter.WriteStartElement("Morphs");
            foreach (Morph morph in ws.Morphs)
            {
                Write("Allomorph", morph.Allomorph);
            }
            m_xmlWriter.WriteEndElement();

            m_xmlWriter.WriteElementString("MPRFeatures", ws.MPRFeatures.ToString());
            m_xmlWriter.WriteElementString("HeadFeatures", ws.HeadFeatures.ToString());
            m_xmlWriter.WriteElementString("FootFeatures", ws.FootFeatures.ToString());

            m_xmlWriter.WriteEndElement();
        }
예제 #19
0
        /// <summary>
        /// Copies a partition from the input phonetic shape to the output phonetic shape.
        /// </summary>
        /// <param name="match">The match.</param>
        /// <param name="input">The input word synthesis.</param>
        /// <param name="output">The output word synthesis.</param>
        /// <param name="morpheme">The morpheme info.</param>
        public override void Apply(Match match, WordSynthesis input, WordSynthesis output, Allomorph allomorph)
        {
            IList <PhoneticShapeNode> nodes = match.GetPartition(m_partition);

            if (nodes != null && nodes.Count > 0)
            {
                Morph morph = null;
                for (PhoneticShapeNode node = nodes[0]; node != nodes[nodes.Count - 1].Next; node = node.Next)
                {
                    PhoneticShapeNode newNode = node.Clone();
                    // mark the reduplicated segments with the gloss partition
                    if (m_redup)
                    {
                        if (allomorph != null)
                        {
                            if (morph == null)
                            {
                                morph = new Morph(allomorph);
                                output.Morphs.Add(morph);
                            }
                            newNode.Partition = morph.Partition;
                            morph.Shape.Add(node.Clone());
                        }
                        else
                        {
                            newNode.Partition = -1;
                        }
                    }
                    else if (node.Partition != -1)
                    {
                        if (morph == null || morph.Partition != node.Partition)
                        {
                            morph = input.Morphs[node.Partition].Clone();
                            morph.Shape.Clear();
                            output.Morphs.Add(morph);
                        }
                        newNode.Partition = morph.Partition;
                        morph.Shape.Add(node.Clone());
                    }
                    output.Shape.Add(newNode);
                }
            }
        }
예제 #20
0
        /// <summary>
        /// Applies the rule to the specified word synthesis.
        /// </summary>
        /// <param name="input">The word synthesis.</param>
        public override void Apply(WordSynthesis input)
        {
            // I don't think there is any difference between iterative and
            // simultaneous application
            Direction dir = Direction.RIGHT;

            switch (m_multApplication)
            {
            case MultAppOrder.LR_ITERATIVE:
            case MultAppOrder.SIMULTANEOUS:
                dir = Direction.RIGHT;
                break;

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

            ProcessIterative(input.Shape, dir, m_lhsTemp, ModeType.SYNTHESIS);
        }
예제 #21
0
 void ApplyRHS(Match headMatch, Match nonHeadMatch, WordSynthesis input, WordSynthesis output)
 {
     output.Shape.Clear();
     output.Morphs.Clear();
     output.Shape.Add(new Margin(Direction.LEFT));
     foreach (MorphologicalOutput outputMember in m_transform.RHS)
     {
         Match         curMatch;
         WordSynthesis curInput;
         if (outputMember.Partition < m_firstNonHeadPartition)
         {
             curMatch = headMatch;
             curInput = input;
         }
         else
         {
             curMatch = nonHeadMatch;
             curInput = input.NonHead;
         }
         outputMember.Apply(curMatch, curInput, output, m_morpheme.Gloss != null ? this : null);
     }
     output.Shape.Add(new Margin(Direction.RIGHT));
 }
예제 #22
0
        void ApplySlots(WordSynthesis input, int sIndex, FeatureValues origHeadFeatures, Set <WordSynthesis> output)
        {
            for (int i = sIndex; i < m_slots.Count; i++)
            {
                foreach (MorphologicalRule rule in m_slots[i].MorphologicalRules)
                {
                    if (rule.IsApplicable(input))
                    {
                        // this is the slot affix that realizes the features
                        ICollection <WordSynthesis> syntheses;
                        if (rule.ApplySlotAffix(input, origHeadFeatures, out syntheses))
                        {
                            foreach (WordSynthesis ws in syntheses)
                            {
                                ApplySlots(ws, i + 1, origHeadFeatures, output);
                            }
                        }
                    }
                }

                if (!m_slots[i].IsOptional)
                {
                    if (Morpher.TraceTemplatesSynthesis)
                    {
                        input.CurrentTrace.AddChild(new TemplateSynthesisTrace(this, false, null));
                    }
                    return;
                }
            }

            if (Morpher.TraceTemplatesSynthesis)
            {
                input.CurrentTrace.AddChild(new TemplateSynthesisTrace(this, false, input.Clone()));
            }
            output.Add(input);
        }
예제 #23
0
        /// <summary>
        /// Inserts the segments and boundaries in to the output phonetic shape.
        /// </summary>
        /// <param name="match">The match.</param>
        /// <param name="input">The input word synthesis.</param>
        /// <param name="output">The output word synthesis.</param>
        /// <param name="morpheme">The morpheme info.</param>
        public override void Apply(Match match, WordSynthesis input, WordSynthesis output, Allomorph allomorph)
        {
            Morph morph = null;

            if (allomorph != null)
            {
                morph = new Morph(allomorph);
                output.Morphs.Add(morph);
            }
            for (PhoneticShapeNode node = m_pshape.Begin; node != m_pshape.Last; node = node.Next)
            {
                PhoneticShapeNode newNode = node.Clone();
                if (morph != null)
                {
                    newNode.Partition = morph.Partition;
                    morph.Shape.Add(node.Clone());
                }
                else
                {
                    newNode.Partition = -1;
                }
                output.Shape.Add(newNode);
            }
        }
예제 #24
0
        /// <summary>
        /// Applies this affix template to the specified input word synthesis.
        /// </summary>
        /// <param name="input">The input word synthesis.</param>
        /// <param name="output">The output word synthesis.</param>
        /// <returns><c>true</c> if the affix template applied, otherwise <c>false</c>.</returns>
        public bool Apply(WordSynthesis input, out IEnumerable <WordSynthesis> output)
        {
            FeatureValues       headFeatures = input.HeadFeatures.Clone();
            Set <WordSynthesis> results      = new Set <WordSynthesis>();

            if (Morpher.TraceTemplatesSynthesis)
            {
                // create the template synthesis input trace record
                TemplateSynthesisTrace tempTrace = new TemplateSynthesisTrace(this, true, input.Clone());
                input.CurrentTrace.AddChild(tempTrace);
            }
            ApplySlots(input.Clone(), 0, headFeatures, results);

            if (results.Count > 0)
            {
                output = results;
                return(true);
            }
            else
            {
                output = null;
                return(false);
            }
        }
예제 #25
0
        /// <summary>
        /// Applies all of the rules to the specified word synthesis.
        /// </summary>
        /// <param name="input">The input word synthesis.</param>
        /// <returns>All word synthesis records that result from the application of rules.</returns>
        public IEnumerable <WordSynthesis> Apply(WordSynthesis input)
        {
            if (m_isCyclic)
            {
                throw new NotImplementedException(HCStrings.kstidCyclicStratumNotSupported);
            }

            if (m_pruleOrder == PRuleOrder.SIMULTANEOUS)
            {
                throw new NotImplementedException(HCStrings.kstidSimultOrderNotSupported);
            }

            // TODO: handle cyclicity
            Set <WordSynthesis> output = new Set <WordSynthesis>();

            ApplyMorphologicalRules(input.Clone(), 0, output);

            foreach (WordSynthesis cur in output)
            {
                ApplyPhonologicalRules(cur);
            }

            return(output);
        }
예제 #26
0
 public override bool IsApplicable(WordSynthesis input)
 {
     return(RealizationalFeatures.IsMatch(input.RealizationalFeatures));
 }
예제 #27
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);
        }
예제 #28
0
 /// <summary>
 /// Initializes a new instance of the <see cref="TemplateSynthesisTrace"/> class.
 /// </summary>
 /// <param name="template">The template.</param>
 /// <param name="input">if <c>true</c> this is an input record, if <c>false</c> this is an output record.</param>
 /// <param name="synthesis">The input or output word synthesis.</param>
 internal TemplateSynthesisTrace(AffixTemplate template, bool input, WordSynthesis synthesis)
     : base(template, input)
 {
     m_synthesis = synthesis;
 }
예제 #29
0
 /// <summary>
 /// Initializes a new instance of the <see cref="PhonologicalRuleSynthesisTrace"/> class.
 /// </summary>
 /// <param name="rule">The rule.</param>
 /// <param name="input">The input.</param>
 internal PhonologicalRuleSynthesisTrace(PhonologicalRule rule, WordSynthesis input)
     : base(rule)
 {
     m_input = input;
 }
예제 #30
0
 /// <summary>
 /// Initializes a new instance of the <see cref="StratumSynthesisTrace"/> class.
 /// </summary>
 /// <param name="stratum">The stratum.</param>
 /// <param name="input">if <c>true</c> this is an input record, if <c>false</c> this is an output record.</param>
 /// <param name="synthesis">The input or output word synthesis.</param>
 internal StratumSynthesisTrace(Stratum stratum, bool input, WordSynthesis synthesis)
     : base(stratum, input)
 {
     m_synthesis = synthesis;
 }