/// <summary> /// Unifies this set of feature values with the specified set of feature values. If the specified /// set of feature values does not contain a feature specified in this set of feature values, then the /// default value will be used for that feature. /// </summary> /// <param name="fv">The feature values.</param> /// <param name="output">The unification.</param> /// <returns><c>true</c> if the feature values could be unified, otherwise <c>false</c>.</returns> public bool UnifyDefaults(FeatureValues fv, out FeatureValues output) { output = fv.Clone(); foreach (KeyValuePair <Feature, ValueInstance> kvp in m_values) { ValueInstance value; if (fv.m_values.TryGetValue(kvp.Key, out value)) { ValueInstance vi = null; if (kvp.Value != null && !kvp.Value.UnifyDefaults(value, out vi)) { output = null; return(false); } output.m_values[kvp.Key] = vi; } else if (kvp.Key.DefaultValue != null) { ValueInstance vi = null; if (kvp.Value != null && !kvp.Value.UnifyDefaults(kvp.Key.DefaultValue, out vi)) { output = null; return(false); } output.m_values[kvp.Key] = vi; } else { output.m_values[kvp.Key] = kvp.Value; } } return(true); }
/// <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>(); }
public bool Equals(FeatureValues other) { if (other == null) { return(false); } if (m_values.Count != other.m_values.Count) { return(false); } foreach (KeyValuePair <Feature, ValueInstance> kvp in m_values) { ValueInstance value; if (!other.m_values.TryGetValue(kvp.Key, out value)) { return(false); } if (kvp.Value != null && !kvp.Value.Equals(value)) { return(false); } } return(true); }
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); }
/// <summary> /// Initializes a new instance of the <see cref="WordAnalysis"/> class. /// </summary> /// <param name="shape">The shape.</param> /// <param name="stratum"></param> internal WordAnalysis(PhoneticShape shape, Stratum stratum) { 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; }
/// <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; }
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)); }
/// <summary> /// Check for if this slot affix was blocked. /// </summary> /// <param name="headFeats">The head features.</param> /// <returns> /// <c>true</c> if this slot affix was blocked, otherwise <c>false</c>. /// </returns> bool IsBlockedSlotAffix(FeatureValues headFeats) { if (RealizationalFeatures.NumFeatures == 0 || headFeats == null) return false; foreach (Feature feature in RealizationalFeatures.Features) { if (!headFeats.ContainsFeature(feature)) return false; } return true; }
/// <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; }
public override void Reset() { base.Reset(); m_requiredPOSs = null; m_outPOS = null; m_maxNumApps = 1; m_requiredHeadFeatures = null; m_requiredFootFeatures = null; m_outHeadFeatures = null; m_outFootFeatures = null; m_obligHeadFeatures = null; m_subrules.Clear(); }
/// <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; }
/// <summary> /// Check for if this slot affix was blocked. /// </summary> /// <param name="headFeats">The head features.</param> /// <returns> /// <c>true</c> if this slot affix was blocked, otherwise <c>false</c>. /// </returns> bool IsBlockedSlotAffix(FeatureValues headFeats) { if (RealizationalFeatures.NumFeatures == 0 || headFeats == null) { return(false); } foreach (Feature feature in RealizationalFeatures.Features) { if (!headFeats.ContainsFeature(feature)) { return(false); } } return(true); }
/// <summary> /// Determines whether the specified set of feature values is compatible with this /// set of feature values. It is much like <c>IsMatch</c> except that if a the /// specified set does not contain a feature in this set, it is still a match. /// It basically checks to make sure that there is no contradictory features. /// </summary> /// <param name="fv">The feature values.</param> /// <returns> /// <c>true</c> the sets are compatible, otherwise <c>false</c>. /// </returns> public bool IsCompatible(FeatureValues fv) { foreach (KeyValuePair <Feature, ValueInstance> kvp in m_values) { ValueInstance value; if (!fv.m_values.TryGetValue(kvp.Key, out value)) { continue; } if (kvp.Value != null && !kvp.Value.IsCompatible(value)) { return(false); } } return(true); }
/// <summary> /// Adds features from the specified set of feature values. If a feature that is in the specified /// set of feature values already exists in this set of feature values, it will not be added. /// </summary> /// <param name="fv">The feature values.</param> public void Add(FeatureValues fv) { foreach (KeyValuePair <Feature, ValueInstance> kvp in fv.m_values) { ValueInstance vi; if (kvp.Value != null && m_values.TryGetValue(kvp.Key, out vi)) { if (kvp.Value.Type == ValueType.COMPLEX) { (vi as FeatureValues).Add(kvp.Value as FeatureValues); } } else { m_values[kvp.Key] = kvp.Value; } } }
/// <summary> /// Gets the difference between this subset and the specified superset. If this set is /// not a subset of the specified superset, it will return <c>false</c>. /// </summary> /// <param name="superset">The superset feature values.</param> /// <param name="remainder">The remainder.</param> /// <returns><c>true</c> if this is a subset, otherwise <c>false</c>.</returns> public bool GetSupersetRemainder(FeatureValues superset, out FeatureValues remainder) { FeatureValues result = superset.Clone(); foreach (KeyValuePair <Feature, ValueInstance> kvp in m_values) { ValueInstance value; if (kvp.Value != null && (!result.m_values.TryGetValue(kvp.Key, out value) || !value.Equals(kvp.Value))) { remainder = null; return(false); } result.m_values.Remove(kvp.Key); } remainder = result; return(true); }
/// <summary> /// Determines whether this set of feature values contains the specified feature. /// </summary> /// <param name="feature">The feature.</param> /// <returns> /// <c>true</c> if this set contains the specified feature, otherwise <c>false</c>. /// </returns> public bool ContainsFeature(Feature feature) { ValueInstance value; if (!m_values.TryGetValue(feature, out value)) { return(false); } FeatureValues fvs = value as FeatureValues; foreach (Feature sf in feature.SubFeatures) { if (fvs == null || !fvs.ContainsFeature(sf)) { return(false); } } return(true); }
/// <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); }
/// <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); } }
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); }
/// <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 abstract bool ApplySlotAffix(WordSynthesis input, FeatureValues origHeadFeatures, out ICollection <WordSynthesis> output);
/// <summary> /// Adds features from the specified set of feature values. If a feature that is in the specified /// set of feature values already exists in this set of feature values, it will not be added. /// </summary> /// <param name="fv">The feature values.</param> public void Add(FeatureValues fv) { foreach (KeyValuePair<Feature, ValueInstance> kvp in fv.m_values) { ValueInstance vi; if (kvp.Value != null && m_values.TryGetValue(kvp.Key, out vi)) { if (kvp.Value.Type == ValueType.COMPLEX) (vi as FeatureValues).Add(kvp.Value as FeatureValues); } else { m_values[kvp.Key] = kvp.Value; } } }
/// <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 abstract bool ApplySlotAffix(WordSynthesis input, FeatureValues origHeadFeatures, out ICollection<WordSynthesis> output);
FeatureValues LoadSynFeats(XmlNode node, FeatureSystem featSys) { FeatureValues fvs = new FeatureValues(); if (node != null) { XmlNodeList featValList = node.SelectNodes("FeatureValueList[@isActive='yes']"); foreach (XmlNode featValNode in featValList) { XmlElement featValElem = featValNode as XmlElement; string featId = featValElem.GetAttribute("feature"); Feature feature = featSys.GetFeature(featId); if (feature == null) throw CreateUndefinedObjectException(string.Format(HCStrings.kstidUnknownFeat, featId), featId); string valueIdsStr = featValElem.GetAttribute("values"); if (!string.IsNullOrEmpty(valueIdsStr)) { string[] valueIds = valueIdsStr.Split(' '); foreach (string valueId in valueIds) { FeatureValue value = feature.GetPossibleValue(valueId); if (value == null) throw CreateUndefinedObjectException(string.Format(HCStrings.kstidUnknownFeatValue, valueId, featId), valueId); fvs.Add(feature, new ClosedValueInstance(value)); } } else { fvs.Add(feature, LoadSynFeats(featValNode, featSys)); } } } return fvs; }
/// <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> /// Initializes a new instance of the <see cref="WordSynthesisTrace"/> class. /// </summary> /// <param name="rootAllomorph">The root allomorph.</param> /// <param name="mrules">The morphological rules.</param> /// <param name="rzFeatures">The realizational features.</param> internal WordSynthesisTrace(LexEntry.RootAllomorph rootAllomorph, IEnumerable <MorphologicalRule> mrules, FeatureValues rzFeatures) { m_rootAllomorph = rootAllomorph; m_mrules = new List <MorphologicalRule>(mrules); m_rzFeatures = rzFeatures; }
public bool Equals(FeatureValues other) { if (other == null) return false; if (m_values.Count != other.m_values.Count) return false; foreach (KeyValuePair<Feature, ValueInstance> kvp in m_values) { ValueInstance value; if (!other.m_values.TryGetValue(kvp.Key, out value)) return false; if (kvp.Value != null && !kvp.Value.Equals(value)) return false; } return true; }
/// <summary> /// Copy constructor. /// </summary> /// <param name="fv">The fv.</param> public FeatureValues(FeatureValues fv) { m_values = new SortedDictionary <Feature, ValueInstance>(fv.m_values); }
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); }
/// <summary> /// Copy constructor. /// </summary> /// <param name="fv">The fv.</param> public FeatureValues(FeatureValues fv) { m_values = new SortedDictionary<Feature, ValueInstance>(fv.m_values); }
/// <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> /// Gets the difference between this subset and the specified superset. If this set is /// not a subset of the specified superset, it will return <c>false</c>. /// </summary> /// <param name="superset">The superset feature values.</param> /// <param name="remainder">The remainder.</param> /// <returns><c>true</c> if this is a subset, otherwise <c>false</c>.</returns> public bool GetSupersetRemainder(FeatureValues superset, out FeatureValues remainder) { FeatureValues result = superset.Clone(); foreach (KeyValuePair<Feature, ValueInstance> kvp in m_values) { ValueInstance value; if (kvp.Value != null && (!result.m_values.TryGetValue(kvp.Key, out value) || !value.Equals(kvp.Value))) { remainder = null; return false; } result.m_values.Remove(kvp.Key); } remainder = result; return true; }
/// <summary> /// Initializes a new instance of the <see cref="WordSynthesisTrace"/> class. /// </summary> /// <param name="rootAllomorph">The root allomorph.</param> /// <param name="mrules">The morphological rules.</param> /// <param name="rzFeatures">The realizational features.</param> internal WordSynthesisTrace(LexEntry.RootAllomorph rootAllomorph, IEnumerable<MorphologicalRule> mrules, FeatureValues rzFeatures) { m_rootAllomorph = rootAllomorph; m_mrules = new List<MorphologicalRule>(mrules); m_rzFeatures = rzFeatures; }
/// <summary> /// Determines whether the specified set of feature values is compatible with this /// set of feature values. It is much like <c>IsMatch</c> except that if a the /// specified set does not contain a feature in this set, it is still a match. /// It basically checks to make sure that there is no contradictory features. /// </summary> /// <param name="fv">The feature values.</param> /// <returns> /// <c>true</c> the sets are compatible, otherwise <c>false</c>. /// </returns> public bool IsCompatible(FeatureValues fv) { foreach (KeyValuePair<Feature, ValueInstance> kvp in m_values) { ValueInstance value; if (!fv.m_values.TryGetValue(kvp.Key, out value)) continue; if (kvp.Value != null && !kvp.Value.IsCompatible(value)) return false; } return true; }
public override void Reset() { base.Reset(); m_headRequiredPOSs = null; m_nonHeadRequiredPOSs = null; m_outPOS = null; m_maxNumApps = 1; m_headRequiredHeadFeatures = null; m_headRequiredFootFeatures = null; m_nonHeadRequiredHeadFeatures = null; m_nonHeadRequiredFootFeatures = null; m_outHeadFeatures = null; m_outFootFeatures = null; m_obligHeadFeatures = null; m_subrules.Clear(); }
/// <summary> /// Unifies this set of feature values with the specified set of feature values. If the specified /// set of feature values does not contain a feature specified in this set of feature values, then the /// default value will be used for that feature. /// </summary> /// <param name="fv">The feature values.</param> /// <param name="output">The unification.</param> /// <returns><c>true</c> if the feature values could be unified, otherwise <c>false</c>.</returns> public bool UnifyDefaults(FeatureValues fv, out FeatureValues output) { output = fv.Clone(); foreach (KeyValuePair<Feature, ValueInstance> kvp in m_values) { ValueInstance value; if (fv.m_values.TryGetValue(kvp.Key, out value)) { ValueInstance vi = null; if (kvp.Value != null && !kvp.Value.UnifyDefaults(value, out vi)) { output = null; return false; } output.m_values[kvp.Key] = vi; } else if (kvp.Key.DefaultValue != null) { ValueInstance vi = null; if (kvp.Value != null && !kvp.Value.UnifyDefaults(kvp.Key.DefaultValue, out vi)) { output = null; return false; } output.m_values[kvp.Key] = vi; } else { output.m_values[kvp.Key] = kvp.Value; } } return true; }
/// <summary> /// Initializes a new instance of the <see cref="WordSynthesis"/> class. /// </summary> /// <param name="rootAllomorph">The root allomorph.</param> /// <param name="rzFeatures">The realizational features.</param> /// <param name="curTrace">The current trace record.</param> internal WordSynthesis(LexEntry.RootAllomorph rootAllomorph, FeatureValues rzFeatures, Trace curTrace) : this(rootAllomorph, null, rzFeatures, new MorphologicalRule[] {}, curTrace) { }
void ApplySlots(WordSynthesis input, int sIndex, FeatureValues origHeadFeatures, TraceManager trace, 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, trace, out syntheses)) { foreach (WordSynthesis ws in syntheses) ApplySlots(ws, i + 1, origHeadFeatures, trace, output); } } } if (!m_slots[i].IsOptional) { if (trace != null) trace.EndApplyTemplate(this, input, false); return; } } if (trace != null) trace.EndApplyTemplate(this, input, true); output.Add(input); }