示例#1
0
		public virtual void Write(WordSynthesis ws, bool prettyPrint)
		{
			if (prettyPrint)
				PrettyPrintWordSynthesis(ws);
			else
				m_out.WriteLine(ws.ToString());
			m_out.WriteLine();
		}
示例#2
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);
		}
示例#3
0
		void PrettyPrintWordSynthesis(WordSynthesis ws)
		{
			var 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);
			m_out.WriteLine(sb.ToString());
		}
示例#4
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();
		}
		/// <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();
		}
示例#6
0
		public override void PhonologicalRuleNotApplicableMPRFeatures(MPRFeaturesType type, WordSynthesis input, MPRFeatureSet mprFeatures)
		{
			if (m_currentSynthesisPruleTrace != null)
				m_currentSynthesisPruleTrace.AddChild(new PhonologicalRuleSynthesisMPRFeaturesTrace(type, input.MPRFeatures, mprFeatures));
		}
示例#7
0
		public override void BeginApplyPhonologicalRule(PhonologicalRule rule, WordSynthesis input)
		{
			if (IsSynthesisTracingEnabled(rule.ID))
			{
				m_currentSynthesisPruleTrace = new PhonologicalRuleSynthesisTrace(rule, input.Clone());
				((Trace) input.CurrentTraceObject).AddChild(m_currentSynthesisPruleTrace);
			}
		}
示例#8
0
		/// <summary>
		/// Applies the rule to the specified word analysis.
		/// </summary>
		/// <param name="input">The input word synthesis.</param>
		/// <param name="output">The output word syntheses.</param>
		/// <returns>
		/// 	<c>true</c> if the rule was successfully applied, otherwise <c>false</c>
		/// </returns>
		public override bool Apply(WordSynthesis input, out ICollection<WordSynthesis> output)
		{
			output = null;

			// these should probably be moved to IsApplicable, but we will leave it here for
			// now so we don't have to call it again to set the features for the output word
			// synthesis record

			// check head features
			FeatureValues headHeadFeatures;
			if (!m_headRequiredHeadFeatures.UnifyDefaults(input.HeadFeatures, out headHeadFeatures))
				return false;

			FeatureValues nonHeadHeadFeatures;
			if (!m_nonHeadRequiredHeadFeatures.UnifyDefaults(input.NonHead.HeadFeatures, out nonHeadHeadFeatures))
				return false;

			// check foot features
			FeatureValues headFootFeatures;
			if (!m_headRequiredFootFeatures.UnifyDefaults(input.FootFeatures, out headFootFeatures))
				return false;

			FeatureValues nonHeadFootFeatures;
			if (!m_nonHeadRequiredFootFeatures.UnifyDefaults(input.NonHead.FootFeatures, out nonHeadFootFeatures))
				return false;

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

			output = new List<WordSynthesis>();
			foreach (Subrule sr in m_subrules)
			{
				WordSynthesis ws;
				if (sr.Apply(input, out ws))
				{
					if (m_outPOS != null)
						ws.POS = m_outPOS;

					if (m_outHeadFeatures != null)
						ws.HeadFeatures = m_outHeadFeatures.Clone();

					ws.HeadFeatures.Add(headHeadFeatures);

					if (m_outFootFeatures != null)
						ws.FootFeatures = m_outFootFeatures.Clone();

					ws.FootFeatures.Add(headFootFeatures);

					if (m_obligHeadFeatures != null)
					{
						foreach (Feature feature in m_obligHeadFeatures)
							ws.AddObligatoryHeadFeature(feature);
					}

					ws.MorphologicalRuleApplied(this);

					ws = CheckBlocking(ws);

					if (trace != null)
					{
						// set current trace record to the morphological rule trace record for each
						// output analysis
						ws.CurrentTrace = trace;
						// add output to morphological rule trace record
						trace.RuleAllomorph = sr;
						trace.Output = ws.Clone();
					}

					output.Add(ws);
					// return all word syntheses that match subrules that are constrained by environments,
					// HC violates the disjunctive property of allomorphs here because it cannot check the
					// environmental constraints until it has a surface form, we will enforce the disjunctive
					// property of allomorphs at that time
					if (sr.RequiredEnvironments == null && sr.ExcludedEnvironments == null)
					{
						break;
					}
				}
			}

			return output.Count > 0;
		}
示例#9
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));
			}
示例#10
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;
		}
示例#11
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;
		}
示例#12
0
		public override void Blocking(BlockType blockingType, WordSynthesis input, LexEntry blockingEntry)
		{
			if (TraceBlocking)
				// create blocking trace record, should this become the current trace?
				((Trace) input.CurrentTraceObject).AddChild(new BlockingTrace(BlockingTrace.BlockType.TEMPLATE, blockingEntry));
		}
示例#13
0
		public override void MorphCooccurrenceRuleFailed(MorphCoOccurrence cooccurrence, string usage, WordSynthesis input)
		{
			if (TraceTemplatesSynthesis)
			{
				var trace = new MorphCoOccurrenceTrace(cooccurrence, usage);
				((Trace)input.CurrentTraceObject).AddChild(trace);

			}
		}
示例#14
0
		public override void MorphologicalRuleNotApplied(MorphologicalRule rule, WordSynthesis input)
		{
			if (IsSynthesisTracingEnabled(rule.ID))
				((Trace) input.CurrentTraceObject).AddChild(new MorphologicalRuleSynthesisTrace(rule, input.Clone()));
		}
示例#15
0
		public override void MorphologicalRuleApplied(MorphologicalRule rule, WordSynthesis input, WordSynthesis output, Allomorph allomorph)
		{
			if (IsSynthesisTracingEnabled(rule.ID))
			{
				var trace = new MorphologicalRuleSynthesisTrace(rule, input.Clone()) {RuleAllomorph = allomorph, Output = output.Clone()};
				((Trace) output.CurrentTraceObject).AddChild(trace);
				// set current trace record to the morphological rule trace record for each
				// output analysis
				output.CurrentTraceObject = trace;
			}
		}
示例#16
0
		public override void EndApplyTemplate(AffixTemplate template, WordSynthesis output, bool applied)
		{
			if (TraceTemplatesSynthesis)
				((Trace) output.CurrentTraceObject).AddChild(new TemplateSynthesisTrace(template, false, applied ? output.Clone() : null));
		}
示例#17
0
		public override void BeginApplyTemplate(AffixTemplate template, WordSynthesis input)
		{
			if (TraceTemplatesSynthesis)
				((Trace) input.CurrentTraceObject).AddChild(new TemplateSynthesisTrace(template, true, input.Clone()));
		}
示例#18
0
		public override void EndApplyPhonologicalRule(PhonologicalRule rule, WordSynthesis output)
		{
			if (m_currentSynthesisPruleTrace != null)
			{
				m_currentSynthesisPruleTrace.Output = output.Clone();
				m_currentSynthesisPruleTrace = null;
			}
		}
示例#19
0
		/// <summary>
		/// Initializes a new instance of the <see cref="MorphologicalRuleSynthesisTrace"/> class.
		/// </summary>
		/// <param name="rule">The rule.</param>
		/// <param name="input">The input.</param>
		internal MorphologicalRuleSynthesisTrace(MorphologicalRule rule, WordSynthesis input)
			: base(rule)
		{
			m_input = input;
		}
示例#20
0
		/// <summary>
		/// Initializes a new instance of the <see cref="ReportSuccessTrace"/> class.
		/// </summary>
		internal ReportSuccessTrace(WordSynthesis output)
		{
			m_output = output;
		}
示例#21
0
		public override void ReportSuccess(WordSynthesis output)
		{
			if (TraceSuccess)
				((Trace) output.CurrentTraceObject).AddChild(new ReportSuccessTrace(output));
		}
示例#22
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;
		}
示例#23
0
            static IEnumerable <PcPatrMorph> GetMorphs(WordSynthesis ws)
            {
                var ppMorphs = new Dictionary <string, PcPatrMorph>();
                var result   = new List <PcPatrMorph>();

                foreach (Morph morph in ws.Morphs)
                {
                    string[]    formIds   = morph.Allomorph.GetProperty("FormID").Split(' ');
                    string[]    wordTypes = morph.Allomorph.GetProperty("WordCategory").Split(' ');
                    string      form      = ws.Stratum.CharacterDefinitionTable.ToString(morph.Shape, ModeType.SYNTHESIS, false);
                    PcPatrMorph ppMorph;
                    if (!ppMorphs.TryGetValue(morph.Allomorph.Morpheme.ID, out ppMorph))
                    {
                        ppMorph = new PcPatrMorph
                        {
                            formIndex = 0,
                            formId    = formIds[0],
                            form      = form,
                            wordType  = wordTypes[0]
                        };
                    }
                    else if (formIds.Length == 1)
                    {
                        ppMorph.form += form;
                        continue;
                    }
                    else
                    {
                        PcPatrMorph oldMorph = ppMorph;
                        ppMorph = new PcPatrMorph
                        {
                            formIndex = oldMorph.formIndex + 1,
                            formId    = formIds[oldMorph.formIndex + 1],
                            form      = form,
                            wordType  = wordTypes[oldMorph.formIndex + 1]
                        };
                    }

                    ppMorph.msaId = morph.Allomorph.GetProperty("MsaID");
                    ppMorph.featureDescriptors = morph.Allomorph.GetProperty("FeatureDescriptors");
                    ppMorph.gloss = morph.Allomorph.Morpheme.Gloss.Description;
                    ppMorphs[morph.Allomorph.Morpheme.ID] = ppMorph;

                    string morphType = morph.Allomorph.GetProperty("MorphType");
                    switch (morphType)
                    {
                    case MoMorphTypeTags.kMorphInfix:
                    case MoMorphTypeTags.kMorphInfixingInterfix:
                        if (result.Count == 0)
                        {
                            result.Add(ppMorph);
                        }
                        else
                        {
                            result.Insert(result.Count - 1, ppMorph);
                        }
                        break;

                    default:
                        result.Add(ppMorph);
                        break;
                    }
                }
                return(result);
            }
示例#24
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;
			}
示例#25
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);
		}
示例#26
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_headRequiredPOSs == null || m_headRequiredPOSs.Count == 0 || m_headRequiredPOSs.Contains(input.POS))
				&& input.NonHead != null
				&& (m_nonHeadRequiredPOSs == null || m_nonHeadRequiredPOSs.Count == 0 || m_nonHeadRequiredPOSs.Contains(input.NonHead.POS));
		}
		/// <summary>
		/// Applies the rule to the specified word synthesis.
		/// </summary>
		/// <param name="input">The input word synthesis.</param>
		/// <param name="output">The output word syntheses.</param>
		/// <returns>
		/// 	<c>true</c> if the rule was successfully applied, otherwise <c>false</c>
		/// </returns>
		public override bool Apply(WordSynthesis input, TraceManager trace, out ICollection<WordSynthesis> output)
		{
			output = null;

			// these should probably be moved to IsApplicable, but we will leave it here for
			// now so we don't have to call it again to set the features for the output word
			// synthesis record

			// check head features
			FeatureValues headFeatures;
			if (!m_requiredHeadFeatures.UnifyDefaults(input.HeadFeatures, out headFeatures))
				return false;

			// check foot features
			FeatureValues footFeatures;
			if (!m_requiredFootFeatures.UnifyDefaults(input.FootFeatures, out footFeatures))
				return false;

			output = new List<WordSynthesis>();
			for (int i = 0; i < m_subrules.Count; i++)
			{
				WordSynthesis ws;
				if (m_subrules[i].Apply(input, out ws))
				{
					if (m_outPOS != null)
						ws.POS = m_outPOS;

					if (m_outHeadFeatures != null)
						ws.HeadFeatures = m_outHeadFeatures.Clone();

					ws.HeadFeatures.Add(headFeatures);

					if (m_outFootFeatures != null)
						ws.FootFeatures = m_outFootFeatures.Clone();

					ws.FootFeatures.Add(footFeatures);

					if (m_obligHeadFeatures != null)
					{
						foreach (Feature feature in m_obligHeadFeatures)
							ws.AddObligatoryHeadFeature(feature);
					}

					ws.MorphologicalRuleApplied(this);

					ws = CheckBlocking(ws, trace);

					if (trace != null)
						trace.MorphologicalRuleApplied(this, input, ws, m_subrules[i]);

					output.Add(ws);
					// return all word syntheses that match subrules that are constrained by environments,
					// HC violates the disjunctive property of allomorphs here because it cannot check the
					// environmental constraints until it has a surface form, we will enforce the disjunctive
					// property of allomorphs at that time

					// HC also checks for free fluctuation, if the next subrule has the same constraints, we
					// do not treat them as disjunctive
					if ((i != m_subrules.Count - 1 && !m_subrules[i].ConstraintsEqual(m_subrules[i + 1]))
						&& m_subrules[i].RequiredEnvironments == null && m_subrules[i].ExcludedEnvironments == null)
					{
						break;
					}
				}
			}

			if (trace != null && output.Count == 0)
				trace.MorphologicalRuleNotApplied(this, input);

			return output.Count > 0;
		}
示例#28
0
		/// <summary>
		/// Applies the rule to the specified word synthesis. This method is used by affix templates.
		/// </summary>
		/// <param name="input">The input word synthesis.</param>
		/// <param name="origHeadFeatures">The original head features before template application.</param>
		/// <param name="output">The output word syntheses.</param>
		/// <returns>
		/// 	<c>true</c> if the rule was successfully applied, otherwise <c>false</c>
		/// </returns>
		public override bool ApplySlotAffix(WordSynthesis input, FeatureValues origHeadFeatures, out ICollection<WordSynthesis> output)
		{
			return Apply(input, out output);
		}
			/// <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)));
			}
			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));
			}
示例#31
0
		public override void PhonologicalRuleNotApplicablePOS(WordSynthesis input, HCObjectSet<PartOfSpeech> requiredPOSs)
		{
			if (m_currentSynthesisPruleTrace != null)
				m_currentSynthesisPruleTrace.AddChild(new PhonologicalRuleSynthesisRequiredPOSTrace(input.POS, requiredPOSs));
		}