예제 #1
0
		/// <summary>
		/// Copy constructor.
		/// </summary>
		/// <param name="ctxt">The simple context.</param>
		public SimpleContext(SimpleContext ctxt)
			: base(ctxt)
		{
			m_featSys = ctxt.m_featSys;
			m_featureValues = new FeatureBundle(ctxt.m_featureValues);
			m_antiFeatureValues = new FeatureBundle(ctxt.m_antiFeatureValues);
		}
예제 #2
0
        /// <summary>
        /// Combines this pattern with the specified pattern. This is used by phonological rules to
        /// generate the RHS target and by morphological rules to generate the RHS template for
        /// modify-from output records. The patterns must be the same size.
        /// </summary>
        /// <param name="pattern">The pattern.</param>
        /// <returns>The phonetic pattern which is a combination of this pattern and the specified pattern.</returns>
        /// <exception cref="System.ArgumentException">Thrown when the size of <c>pattern</c> does not match the size of this pattern.</exception>
        public PhoneticPattern Combine(PhoneticPattern pattern)
        {
            if (Count != pattern.Count)
            {
                throw new ArgumentException(HCStrings.kstidPatternCombine, "pattern");
            }

            PhoneticPattern     result  = new PhoneticPattern();
            PhoneticPatternNode lhsNode = pattern.First;

            foreach (PhoneticPatternNode rhsNode in this)
            {
                // combine the simple contexts
                if (rhsNode.Type == PhoneticPatternNode.NodeType.SIMP_CTXT &&
                    lhsNode.Type == PhoneticPatternNode.NodeType.SIMP_CTXT)
                {
                    SimpleContext rhsCtxt = rhsNode as SimpleContext;
                    SimpleContext lhsCtxt = lhsNode as SimpleContext;

                    result.Add(rhsCtxt.Combine(lhsCtxt));
                }
                lhsNode = lhsNode.GetNext();
            }

            return(result);
        }
예제 #3
0
            /// <summary>
            /// Checks for overlap of features between the specified simple context and the specified
            /// environment.
            /// </summary>
            /// <param name="ctxt">The simple context.</param>
            /// <param name="envSeq">The environment.</param>
            /// <returns>
            ///     <c>true</c> if there is no overlap, otherwise <c>false</c>.
            /// </returns>
            bool IsNonSelfOpaquing(SimpleContext ctxt, PhoneticPattern env)
            {
                foreach (PhoneticPatternNode node in env)
                {
                    switch (node.Type)
                    {
                    case PhoneticPatternNode.NodeType.SIMP_CTXT:
                        SimpleContext envCtxt = node as SimpleContext;
                        if (!envCtxt.FeatureValues.IsDisjoint(ctxt.AntiFeatureValues))
                        {
                            return(false);
                        }
                        break;

                    case PhoneticPatternNode.NodeType.BDRY_CTXT:
                        break;

                    case PhoneticPatternNode.NodeType.PATTERN:
                        NestedPhoneticPattern optSeq = node as NestedPhoneticPattern;
                        if (!IsNonSelfOpaquing(ctxt, optSeq.Pattern))
                        {
                            return(false);
                        }
                        break;
                    }
                }

                return(true);
            }
예제 #4
0
 /// <summary>
 /// Copy constructor.
 /// </summary>
 /// <param name="ctxt">The simple context.</param>
 public SimpleContext(SimpleContext ctxt)
     : base(ctxt)
 {
     m_featSys           = ctxt.m_featSys;
     m_featureValues     = new FeatureBundle(ctxt.m_featureValues);
     m_antiFeatureValues = new FeatureBundle(ctxt.m_antiFeatureValues);
 }
예제 #5
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;
                }
            }
        }
예제 #6
0
        protected override SimpleContext CombineFeatures(SimpleContext ctxt)
        {
            NaturalClassContext result = base.CombineFeatures(ctxt) as NaturalClassContext;

            if (ctxt.ContextType == SimpleContextType.NATURAL_CLASS)
            {
                NaturalClassContext ncCtxt = ctxt as NaturalClassContext;
                // add variables from the specified pattern's context
                foreach (KeyValuePair <string, bool> varPolarity in ncCtxt.m_variables)
                {
                    if (!Owner.IsFeatureReferenced(m_alphaVars.GetFeature(varPolarity.Key)))
                    {
                        result.m_variables[varPolarity.Key] = varPolarity.Value;
                    }
                }

                foreach (KeyValuePair <string, bool> varPolarity in ncCtxt.m_antiVariables)
                {
                    if (!Owner.IsFeatureReferenced(m_alphaVars.GetFeature(varPolarity.Key)))
                    {
                        result.m_antiVariables[varPolarity.Key] = varPolarity.Value;
                    }
                }
            }
            return(result);
        }
예제 #7
0
 public SimpleContext Combine(SimpleContext ctxt)
 {
     if (m_featSys.HasFeatures)
     {
         return(CombineFeatures(ctxt));
     }
     else
     {
         return(Clone() as SimpleContext);
     }
 }
예제 #8
0
            /// <summary>
            /// Applies the RHS to the matched segments.
            /// </summary>
            /// <param name="dir">The direction.</param>
            /// <param name="match">The matched segments.</param>
            /// <param name="instantiatedVars">The instantiated variables.</param>
            public void ApplyRHS(Direction dir, IList <PhoneticShapeNode> match, VariableValues instantiatedVars)
            {
                switch (Type)
                {
                case ChangeType.FEATURE:
                    int i = 0;
                    for (PhoneticPatternNode pseqNode = m_rhs.GetFirst(dir); pseqNode != null;
                         pseqNode = pseqNode.GetNext(dir))
                    {
                        switch (pseqNode.Type)
                        {
                        case PhoneticPatternNode.NodeType.SIMP_CTXT:
                            SimpleContext ctxt = pseqNode as SimpleContext;
                            // match[i] should be a segment, should I check that here?
                            while (match[i].Type == PhoneticShapeNode.NodeType.BOUNDARY)
                            {
                                i++;
                            }
                            Segment seg = match[i] as Segment;
                            ctxt.Apply(seg, instantiatedVars);
                            // marked the segment as altered
                            seg.IsClean = false;
                            break;

                        case PhoneticPatternNode.NodeType.BDRY_CTXT:
                            // boundaries should match, should I check that here?
                            break;
                        }
                        i++;
                    }
                    break;

                case ChangeType.NARROW:
                    ApplyInsertion(dir, match, instantiatedVars);
                    // remove matching segments
                    foreach (PhoneticShapeNode node in match)
                    {
                        node.Remove();
                    }
                    break;

                case ChangeType.EPENTHESIS:
                    // insert new segments or boundaries
                    ApplyInsertion(dir, match, instantiatedVars);
                    break;
                }
            }
예제 #9
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);
            }
예제 #10
0
            /// <summary>
            /// Checks if the subrule will be unapplied vacuously. Vacuous unapplication means that
            /// the subrule will actually make changes to the phonetic shape. This is important to know
            /// for self-opaquing, simultaneously applying subrules, since we unapply these subrules
            /// until they unapply nonvacuously.
            /// </summary>
            /// <param name="match">The match.</param>
            /// <param name="dir">The direction.</param>
            /// <returns></returns>
            bool CheckVacuousUnapplication(Match match, Direction dir)
            {
                PhoneticPatternNode       rhsNode = m_rhs.GetFirst(dir);
                IList <PhoneticShapeNode> nodes   = match.EntireMatch;
                int i = 0;

                while (i < nodes.Count)
                {
                    if (Type == ChangeType.EPENTHESIS)
                    {
                        // for epenthesis subrules, simply check if the epenthesized segment is
                        // already marked as optional
                        if (!nodes[i++].IsOptional)
                        {
                            return(true);
                        }
                    }
                    else
                    {
                        switch (rhsNode.Type)
                        {
                        case PhoneticPatternNode.NodeType.SIMP_CTXT:
                            SimpleContext ctxt = rhsNode as SimpleContext;
                            Segment       seg  = nodes[i] as Segment;
                            if (ctxt.IsUnapplicationVacuous(seg, match.VariableValues))
                            {
                                return(true);
                            }
                            i++;
                            break;

                        case PhoneticPatternNode.NodeType.BDRY_CTXT:
                            break;
                        }

                        rhsNode = rhsNode.GetNext(dir);
                    }
                }

                return(false);
            }
예제 #11
0
            void UnapplyRHS(Direction dir, IList <PhoneticShapeNode> match, VariableValues instantiatedVars)
            {
                switch (Type)
                {
                case ChangeType.FEATURE:
                    int i = 0;
                    // if there are no phonetic features, unapply using the LHS, since we are simply replacing
                    PhoneticPattern unappPattern = m_rule.Morpher.PhoneticFeatureSystem.HasFeatures ? m_analysisTarget : m_rule.m_lhs;
                    for (PhoneticPatternNode pseqNode = unappPattern.GetFirst(dir); pseqNode != null;
                         pseqNode = pseqNode.GetNext(dir))
                    {
                        switch (pseqNode.Type)
                        {
                        case PhoneticPatternNode.NodeType.SIMP_CTXT:
                            SimpleContext ctxt = pseqNode as SimpleContext;
                            // match[i] should be a segment, should I check that here?
                            Segment seg = match[i] as Segment;
                            ctxt.Unapply(seg, instantiatedVars);
                            break;

                        case PhoneticPatternNode.NodeType.BDRY_CTXT:
                            // skip boundaries
                            continue;
                        }
                        i++;
                    }
                    break;

                case ChangeType.EPENTHESIS:
                    // do not remove epenthesized segments, since it is possible that they will not
                    // be epenthesized during synthesis, we just mark them as optional
                    foreach (PhoneticShapeNode node in match)
                    {
                        node.IsOptional = true;
                    }
                    break;
                }
            }
예제 #12
0
            void ApplyInsertion(Direction dir, IList <PhoneticShapeNode> match, VariableValues instantiatedVars)
            {
                PhoneticShapeNode cur = match[match.Count - 1];

                for (PhoneticPatternNode pseqNode = m_rhs.GetFirst(dir); pseqNode != null;
                     pseqNode = pseqNode.GetNext(dir))
                {
                    PhoneticShapeNode newNode = null;
                    switch (pseqNode.Type)
                    {
                    case PhoneticPatternNode.NodeType.SIMP_CTXT:
                        SimpleContext ctxt = pseqNode as SimpleContext;
                        newNode = ctxt.ApplyInsertion(instantiatedVars);
                        break;

                    case PhoneticPatternNode.NodeType.BDRY_CTXT:
                        newNode = new Boundary(pseqNode as BoundaryContext);
                        break;
                    }

                    if (newNode != null)
                    {
                        try
                        {
                            cur.Insert(newNode, dir);
                        }
                        catch (InvalidOperationException ioe)
                        {
                            MorphException me = new MorphException(MorphException.MorphErrorType.TOO_MANY_SEGS, m_rule.Morpher,
                                                                   string.Format(HCStrings.kstidTooManySegs, m_rule.ID), ioe);
                            me.Data["rule"] = m_rule.ID;
                            throw me;
                        }
                        cur = newNode;
                    }
                }
            }
예제 #13
0
        protected virtual SimpleContext CombineFeatures(SimpleContext ctxt)
        {
            SimpleContext result = Clone() as SimpleContext;

            // collect all of the possible values of the features
            List <FeatureValue> featVals = new List <FeatureValue>();

            foreach (Feature feature in Owner.Features)
            {
                featVals.AddRange(feature.PossibleValues);
            }
            // create a mask feature bundle from all possible values
            FeatureBundle mask = new FeatureBundle(featVals, m_featSys);

            FeatureBundle temp = ctxt.FeatureValues.Clone();

            // remove features referenced in the this pattern's context
            temp.RemoveValues(mask);
            // add remaining features from the specified pattern's context to this pattern's context
            result.FeatureValues.AddValues(temp);
            // remove anti features referenced in the specified pattern's context from this pattern's context
            result.AntiFeatureValues.RemoveValues(ctxt.AntiFeatureValues);
            return(result);
        }
예제 #14
0
 /// <summary>
 /// Initializes a new instance of the <see cref="ModifyFromInput"/> class.
 /// </summary>
 /// <param name="partition">The partition to modify.</param>
 /// <param name="ctxt">The simple context.</param>
 /// <param name="morpher">The morpher.</param>
 public ModifyFromInput(int partition, SimpleContext ctxt, Morpher morpher)
 {
     m_partition = partition;
     m_ctxt      = ctxt;
     m_morpher   = morpher;
 }
예제 #15
0
 /// <summary>
 /// Initializes a new instance of the <see cref="InsertSimpleContext"/> class.
 /// </summary>
 /// <param name="ctxt">The simple context.</param>
 public InsertSimpleContext(SimpleContext ctxt)
 {
     m_ctxt = ctxt;
 }
예제 #16
0
		/// <summary>
		/// Initializes a new instance of the <see cref="ModifyFromInput"/> class.
		/// </summary>
		/// <param name="partition">The partition to modify.</param>
		/// <param name="ctxt">The simple context.</param>
		/// <param name="morpher">The morpher.</param>
		public ModifyFromInput(int partition, SimpleContext ctxt, Morpher morpher)
		{
			m_partition = partition;
			m_ctxt = ctxt;
			m_morpher = morpher;
		}
예제 #17
0
		/// <summary>
		/// Initializes a new instance of the <see cref="InsertSimpleContext"/> class.
		/// </summary>
		/// <param name="ctxt">The simple context.</param>
		public InsertSimpleContext(SimpleContext ctxt)
		{
			m_ctxt = ctxt;
		}
예제 #18
0
		protected override SimpleContext CombineFeatures(SimpleContext ctxt)
		{
			NaturalClassContext result = base.CombineFeatures(ctxt) as NaturalClassContext;
			if (ctxt.ContextType == SimpleContextType.NATURAL_CLASS)
			{
				NaturalClassContext ncCtxt = ctxt as NaturalClassContext;
				// add variables from the specified pattern's context
				foreach (KeyValuePair<string, bool> varPolarity in ncCtxt.m_variables)
				{
					if (!Owner.IsFeatureReferenced(m_alphaVars.GetFeature(varPolarity.Key)))
						result.m_variables[varPolarity.Key] = varPolarity.Value;
				}

				foreach (KeyValuePair<string, bool> varPolarity in ncCtxt.m_antiVariables)
				{
					if (!Owner.IsFeatureReferenced(m_alphaVars.GetFeature(varPolarity.Key)))
						result.m_antiVariables[varPolarity.Key] = varPolarity.Value;
				}
			}
			return result;
		}
예제 #19
0
		protected virtual SimpleContext CombineFeatures(SimpleContext ctxt)
		{
			SimpleContext result = Clone() as SimpleContext;

			// collect all of the possible values of the features
			List<FeatureValue> featVals = new List<FeatureValue>();
			foreach (Feature feature in Owner.Features)
				featVals.AddRange(feature.PossibleValues);
			// create a mask feature bundle from all possible values
			FeatureBundle mask = new FeatureBundle(featVals, m_featSys);

			FeatureBundle temp = ctxt.FeatureValues.Clone();
			// remove features referenced in the this pattern's context
			temp.RemoveValues(mask);
			// add remaining features from the specified pattern's context to this pattern's context
			result.FeatureValues.AddValues(temp);
			// remove anti features referenced in the specified pattern's context from this pattern's context
			result.AntiFeatureValues.RemoveValues(ctxt.AntiFeatureValues);
			return result;
		}
예제 #20
0
			/// <summary>
			/// Checks for overlap of features between the specified simple context and the specified
			/// environment.
			/// </summary>
			/// <param name="ctxt">The simple context.</param>
			/// <param name="envSeq">The environment.</param>
			/// <returns>
			/// 	<c>true</c> if there is no overlap, otherwise <c>false</c>.
			/// </returns>
			bool IsNonSelfOpaquing(SimpleContext ctxt, PhoneticPattern env)
			{
				foreach (PhoneticPatternNode node in env)
				{
					switch (node.Type)
					{
						case PhoneticPatternNode.NodeType.SIMP_CTXT:
							SimpleContext envCtxt = node as SimpleContext;
							if (!envCtxt.FeatureValues.IsDisjoint(ctxt.AntiFeatureValues))
								return false;
							break;

						case PhoneticPatternNode.NodeType.BDRY_CTXT:
							break;

						case PhoneticPatternNode.NodeType.PATTERN:
							NestedPhoneticPattern optSeq = node as NestedPhoneticPattern;
							if (!IsNonSelfOpaquing(ctxt, optSeq.Pattern))
								return false;
							break;
					}
				}

				return true;
			}
예제 #21
0
		public SimpleContext Combine(SimpleContext ctxt)
		{
			if (m_featSys.HasFeatures)
				return CombineFeatures(ctxt);
			else
				return Clone() as SimpleContext;
		}