Skip to content

Commit 6ba44b8

Browse files
authored
LT-22266 Add feature constraints for IMoAffixProcess (#348)
Change-Id: I4f03955310df07d6958598c504f02115d4564893
1 parent 0bc98fb commit 6ba44b8

File tree

3 files changed

+178
-0
lines changed

3 files changed

+178
-0
lines changed

src/SIL.LCModel/DomainImpl/OverridesLing_MoClasses.cs

Lines changed: 120 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4066,6 +4066,126 @@ public override void PostClone(Dictionary<int, ICmObject> copyMap)
40664066
clonedProcess.OutputOS.RemoveAt(0);
40674067
}
40684068
}
4069+
/// <summary>
4070+
/// Gets all of the feature constraints in this rule.
4071+
/// </summary>
4072+
/// <value>The feature constraints.</value>
4073+
[VirtualProperty(CellarPropertyType.ReferenceCollection, "PhFeatureConstraint")]
4074+
public IEnumerable<IPhFeatureConstraint> FeatureConstraints
4075+
{
4076+
get
4077+
{
4078+
return GetFeatureConstraints();
4079+
}
4080+
}
4081+
4082+
/// <summary>
4083+
/// Gets all of the feature constraints in this rule.
4084+
/// </summary>
4085+
/// <returns>The feature constraints.</returns>
4086+
public List<IPhFeatureConstraint> GetFeatureConstraints()
4087+
{
4088+
var featureConstrs = new List<IPhFeatureConstraint>();
4089+
CollectVars(InputOS, featureConstrs);
4090+
var contents = new List<IPhContextOrVar>();
4091+
foreach (var ruleMapping in OutputOS)
4092+
{
4093+
switch (ruleMapping.ClassID)
4094+
{
4095+
case MoCopyFromInputTags.kClassId:
4096+
var copyInput = ruleMapping as IMoCopyFromInput;
4097+
if (copyInput != null && copyInput.ContentRA != null)
4098+
{
4099+
contents.Add(copyInput.ContentRA);
4100+
}
4101+
break;
4102+
case MoModifyFromInputTags.kClassId:
4103+
var modInput = ruleMapping as IMoModifyFromInput;
4104+
if (modInput != null && modInput.ContentRA != null)
4105+
{
4106+
contents.Add(modInput.ContentRA);
4107+
}
4108+
break;
4109+
}
4110+
}
4111+
CollectVars(contents, featureConstrs);
4112+
return featureConstrs;
4113+
}
4114+
4115+
/// <summary>
4116+
/// Collects all of the alpha variables in the specified sequence of contexts.
4117+
/// </summary>
4118+
/// <param name="seq">The sequence.</param>
4119+
/// <param name="featureConstrs">The feature constraints.</param>
4120+
void CollectVars(IEnumerable<IPhContextOrVar> seq, List<IPhFeatureConstraint> featureConstrs)
4121+
{
4122+
foreach (var ctxt in seq)
4123+
{
4124+
if (ctxt.ClassID == PhSequenceContextTags.kClassId)
4125+
{
4126+
IPhSequenceContext psc = ctxt as IPhSequenceContext;
4127+
if (psc == null)
4128+
continue;
4129+
foreach (var memb in psc.MembersRS)
4130+
{
4131+
if (memb.ClassID == PhSimpleContextNCTags.kClassId)
4132+
{
4133+
var ncMemb = memb as IPhSimpleContextNC;
4134+
CollectVars(ncMemb, featureConstrs);
4135+
}
4136+
}
4137+
}
4138+
else if (ctxt.ClassID == PhSimpleContextNCTags.kClassId)
4139+
{
4140+
var ncCtxt = ctxt as IPhSimpleContextNC;
4141+
CollectVars(ncCtxt, featureConstrs);
4142+
}
4143+
}
4144+
}
4145+
/// <summary>
4146+
/// Collects all of the alpha variables in the specified sequence of contexts.
4147+
/// </summary>
4148+
/// <param name="ctxt">The context.</param>
4149+
/// <param name="featureConstrs">The feature indices.</param>
4150+
void CollectVars(IPhPhonContext ctxt, List<IPhFeatureConstraint> featureConstrs)
4151+
{
4152+
if (ctxt == null)
4153+
return;
4154+
4155+
switch (ctxt.ClassID)
4156+
{
4157+
case PhSequenceContextTags.kClassId:
4158+
var seqCtxt = (IPhSequenceContext)ctxt;
4159+
foreach (var cur in seqCtxt.MembersRS)
4160+
CollectVars(cur as IPhSimpleContextNC, featureConstrs);
4161+
break;
4162+
4163+
case PhIterationContextTags.kClassId:
4164+
var iterCtxt = (IPhIterationContext)ctxt;
4165+
CollectVars(iterCtxt.MemberRA, featureConstrs);
4166+
break;
4167+
4168+
case PhSimpleContextNCTags.kClassId:
4169+
var ncCtxt = (IPhSimpleContextNC)ctxt;
4170+
CollectVars(ncCtxt.PlusConstrRS, featureConstrs);
4171+
CollectVars(ncCtxt.MinusConstrRS, featureConstrs);
4172+
break;
4173+
}
4174+
}
4175+
4176+
/// <summary>
4177+
/// Collects all of the alpha variables in the specified sequence.
4178+
/// </summary>
4179+
/// <param name="vars">The sequence of variables.</param>
4180+
/// <param name="featureConstrs">The feature constraints.</param>
4181+
void CollectVars(IEnumerable<IPhFeatureConstraint> vars, List<IPhFeatureConstraint> featureConstrs)
4182+
{
4183+
foreach (var var in vars)
4184+
{
4185+
if (!featureConstrs.Contains(var))
4186+
featureConstrs.Add(var);
4187+
}
4188+
}
40694189
}
40704190

40714191
internal partial class MoMorphData

src/SIL.LCModel/InterfaceAdditions.cs

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2107,6 +2107,24 @@ public partial interface IMoInflAffixSlot : ICloneableCmObject
21072107
IEnumerable<ILexEntry> OtherInflectionalAffixLexEntries { get; }
21082108
}
21092109

2110+
public partial interface IMoAffixProcess
2111+
{
2112+
/// <summary>
2113+
/// Gets all of the feature constraints in this rule.
2114+
/// </summary>
2115+
/// <value>The feature constraints.</value>
2116+
IEnumerable<IPhFeatureConstraint> FeatureConstraints
2117+
{
2118+
get;
2119+
}
2120+
2121+
/// <summary>
2122+
/// Gets all of the feature constraints in this rule.
2123+
/// </summary>
2124+
/// <returns>The feature constraints.</returns>
2125+
public List<IPhFeatureConstraint> GetFeatureConstraints();
2126+
}
2127+
21102128
public partial interface IFsFeatureSystem
21112129
{
21122130
/// <summary>

tests/SIL.LCModel.Tests/DomainImpl/LingTests.cs

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,46 @@ public void NewMoAffixProcessHasInputAndOutput()
106106
Assert.That(affixProcess.OutputOS[0], Is.TypeOf(typeof(MoCopyFromInput)));
107107
}
108108

109+
/// <summary>
110+
/// Verify that a new MoAffixProcess is properly initialized. This is needed at least for the Affix Process slice
111+
/// to work properly. See FWR-1619.
112+
/// </summary>
113+
[Test]
114+
public void MoAffixProcessFeatureConstraints()
115+
{
116+
var phData = Cache.LangProject.PhonologicalDataOA;
117+
var entry = Cache.ServiceLocator.GetInstance<ILexEntryFactory>().Create();
118+
var affixProcess = Cache.ServiceLocator.GetInstance<IMoAffixProcessFactory>().Create();
119+
entry.LexemeFormOA = affixProcess;
120+
121+
var ctxtInput = Cache.ServiceLocator.GetInstance<IPhSimpleContextNCFactory>().Create();
122+
affixProcess.InputOS.Add(ctxtInput);
123+
var featConstrInput = Cache.ServiceLocator.GetInstance<IPhFeatureConstraintFactory>().Create();
124+
phData.FeatConstraintsOS.Add(featConstrInput);
125+
ctxtInput.PlusConstrRS.Add(featConstrInput);
126+
127+
var cfi = Cache.ServiceLocator.GetInstance<IMoCopyFromInputFactory>().Create();
128+
affixProcess.OutputOS.Add(cfi);
129+
var ctxtCfi = Cache.ServiceLocator.GetInstance<IPhSimpleContextNCFactory>().Create();
130+
phData.ContextsOS.Add(ctxtCfi);
131+
cfi.ContentRA = ctxtCfi;
132+
var featConstrCfi = Cache.ServiceLocator.GetInstance<IPhFeatureConstraintFactory>().Create();
133+
phData.FeatConstraintsOS.Add(featConstrCfi);
134+
ctxtCfi.MinusConstrRS.Add(featConstrCfi);
135+
136+
var mfi = Cache.ServiceLocator.GetInstance<IMoModifyFromInputFactory>().Create();
137+
affixProcess.OutputOS.Add(mfi);
138+
var ctxtMfi = Cache.ServiceLocator.GetInstance<IPhSimpleContextNCFactory>().Create();
139+
phData.ContextsOS.Add(ctxtMfi);
140+
mfi.ContentRA = ctxtMfi;
141+
var featConstrMfi = Cache.ServiceLocator.GetInstance<IPhFeatureConstraintFactory>().Create();
142+
phData.FeatConstraintsOS.Add(featConstrMfi);
143+
ctxtMfi.PlusConstrRS.Add(featConstrMfi);
144+
145+
var featureConstrs = affixProcess.FeatureConstraints;
146+
Assert.That(featureConstrs, Has.Count.EqualTo(3));
147+
}
148+
109149
/// <summary>
110150
/// Trivial test that a newly created InflAffixTemplate has the Final property set to true.
111151
/// </summary>

0 commit comments

Comments
 (0)