/// <summary> /// Determines which morphological output records result in a reduplicated affix. It /// makes educated guesses. /// </summary> /// <returns></returns> void CheckReduplication(RedupMorphType redupMorphType) { Dictionary <int, List <int> > partMembers = new Dictionary <int, List <int> >(); // collect all of the output records for each partition for (int i = 0; i < m_rhs.Count; i++) { if (m_rhs[i].Partition > -1) { List <int> members; if (!partMembers.TryGetValue(m_rhs[i].Partition, out members)) { members = new List <int>(); partMembers[m_rhs[i].Partition] = members; } members.Add(i); } } // remove all partitions that have only one output record, so all that is // left are the reduplicated partitions List <int> toRemove = new List <int>(); foreach (KeyValuePair <int, List <int> > kvp in partMembers) { if (kvp.Value.Count == 1) { toRemove.Add(kvp.Key); } } foreach (int member in toRemove) { partMembers.Remove(member); } if (partMembers.Count > 0) { int start = -1; // we have some reduplicated partitions switch (redupMorphType) { case RedupMorphType.PREFIX: int prefixPartition = m_lhs.Count - 1; for (int i = m_rhs.Count - 1; i >= 0; i--) { if (m_rhs[i].Partition == prefixPartition || m_rhs[i].Partition == m_lhs.Count - 1) { if (m_rhs[i].Partition == 0) { start = i; break; } prefixPartition = m_rhs[i].Partition - 1; } else { prefixPartition = m_lhs.Count - 1; } } break; case RedupMorphType.SUFFIX: case RedupMorphType.IMPLICIT: int suffixPartition = 0; // look for the full word in the RHS by looking for all of the LHS // partitions in order for (int i = 0; i < m_rhs.Count; i++) { if (m_rhs[i].Partition == suffixPartition || m_rhs[i].Partition == 0) { if (m_rhs[i].Partition == m_lhs.Count - 1) { start = i - (m_lhs.Count - 1); break; } suffixPartition = m_rhs[i].Partition + 1; } else { suffixPartition = 0; } } break; } // now mark the RHS output records that are not part of the full word // as the output records that generate the reduplicated segments foreach (List <int> members in partMembers.Values) { for (int j = 0; j < members.Count; j++) { int index = members[j]; if (start == -1) { m_rhs[index].IsReduplication = j != members.Count - 1; } else { m_rhs[index].IsReduplication = index < start || index >= start + m_lhs.Count; } } } } }
/// <summary> /// Determines which morphological output records result in a reduplicated affix. It /// makes educated guesses. /// </summary> /// <returns></returns> void CheckReduplication(RedupMorphType redupMorphType) { Dictionary<int, List<int>> partMembers = new Dictionary<int, List<int>>(); // collect all of the output records for each partition for (int i = 0; i < m_rhs.Count; i++) { if (m_rhs[i].Partition > -1) { List<int> members; if (!partMembers.TryGetValue(m_rhs[i].Partition, out members)) { members = new List<int>(); partMembers[m_rhs[i].Partition] = members; } members.Add(i); } } // remove all partitions that have only one output record, so all that is // left are the reduplicated partitions List<int> toRemove = new List<int>(); foreach (KeyValuePair<int, List<int>> kvp in partMembers) { if (kvp.Value.Count == 1) toRemove.Add(kvp.Key); } foreach (int member in toRemove) partMembers.Remove(member); if (partMembers.Count > 0) { int start = -1; // we have some reduplicated partitions switch (redupMorphType) { case RedupMorphType.PREFIX: int prefixPartition = m_lhs.Count - 1; for (int i = m_rhs.Count - 1; i >= 0; i--) { if (m_rhs[i].Partition == prefixPartition || m_rhs[i].Partition == m_lhs.Count - 1) { if (m_rhs[i].Partition == 0) { start = i; break; } prefixPartition = m_rhs[i].Partition - 1; } else { prefixPartition = m_lhs.Count - 1; } } break; case RedupMorphType.SUFFIX: case RedupMorphType.IMPLICIT: int suffixPartition = 0; // look for the full word in the RHS by looking for all of the LHS // partitions in order for (int i = 0; i < m_rhs.Count; i++) { if (m_rhs[i].Partition == suffixPartition || m_rhs[i].Partition == 0) { if (m_rhs[i].Partition == m_lhs.Count - 1) { start = i - (m_lhs.Count - 1); break; } suffixPartition = m_rhs[i].Partition + 1; } else { suffixPartition = 0; } } break; } // now mark the RHS output records that are not part of the full word // as the output records that generate the reduplicated segments foreach (List<int> members in partMembers.Values) { for (int j = 0; j < members.Count; j++) { int index = members[j]; if (start == -1) m_rhs[index].IsReduplication = j != members.Count - 1; else m_rhs[index].IsReduplication = index < start || index >= start + m_lhs.Count; } } } }
/// <summary> /// Initializes a new instance of the <see cref="MorphologicalTransform"/> class. /// </summary> /// <param name="lhs">The LHS.</param> /// <param name="rhs">The RHS.</param> public MorphologicalTransform(IEnumerable <PhoneticPattern> lhs, IEnumerable <MorphologicalOutput> rhs, RedupMorphType redupMorphType) { m_lhs = new List <PhoneticPattern>(lhs); m_rhs = new List <MorphologicalOutput>(rhs); m_modifyFromCtxts = new Dictionary <int, SimpleContext>(); // reduplication flags for each morphological output record CheckReduplication(redupMorphType); m_rhsTemp = new PhoneticPattern(); m_modifyFromCtxts = new Dictionary <int, SimpleContext>(); m_rhsTemp.Add(new MarginContext(Direction.LEFT)); for (int i = 0; i < m_rhs.Count; i++) { m_rhs[i].GenerateRHSTemplate(m_rhsTemp, m_lhs, m_modifyFromCtxts); } m_rhsTemp.Add(new MarginContext(Direction.RIGHT)); }
/// <summary> /// Initializes a new instance of the <see cref="MorphologicalTransform"/> class. /// </summary> /// <param name="lhs">The LHS.</param> /// <param name="rhs">The RHS.</param> public MorphologicalTransform(IEnumerable<PhoneticPattern> lhs, IEnumerable<MorphologicalOutput> rhs, RedupMorphType redupMorphType) { m_lhs = new List<PhoneticPattern>(lhs); m_rhs = new List<MorphologicalOutput>(rhs); m_modifyFromCtxts = new Dictionary<int, SimpleContext>(); // reduplication flags for each morphological output record CheckReduplication(redupMorphType); m_rhsTemp = new PhoneticPattern(); m_modifyFromCtxts = new Dictionary<int, SimpleContext>(); m_rhsTemp.Add(new MarginContext(Direction.LEFT)); for (int i = 0; i < m_rhs.Count; i++) m_rhs[i].GenerateRHSTemplate(m_rhsTemp, m_lhs, m_modifyFromCtxts); m_rhsTemp.Add(new MarginContext(Direction.RIGHT)); }