LotSizingDataModel.Instance 2.0.1
Lot-sizing instance representation, descriptors and problem characterization.
Loading...
Searching...
No Matches
ClassificationEvidence.cs
Go to the documentation of this file.
1using System;
2using System.Xml.Serialization;
3using LotSizingDataModel.Core.Common;
4
6
7/// <summary>
8/// Represents one factual element used to evaluate whether
9/// a lot-sizing instance matches a known problem family.
10/// </summary>
11/// <remarks>
12/// A classification match normally contains several evidence
13/// objects.
14///
15/// Each object records:
16/// <list type="bullet">
17/// <item>
18/// <description>the feature that was evaluated;</description>
19/// </item>
20/// <item>
21/// <description>the expected value;</description>
22/// </item>
23/// <item>
24/// <description>the observed value;</description>
25/// </item>
26/// <item>
27/// <description>whether the condition was satisfied;</description>
28/// </item>
29/// <item>
30/// <description>whether the condition was mandatory.</description>
31/// </item>
32/// </list>
33///
34/// This class records evaluation results only. It does not
35/// independently determine whether a complete problem-family
36/// match is exact, partial or approximate.
37/// </remarks>
38[Serializable]
39[XmlType(TypeName = "classificationEvidence")]
40public sealed class ClassificationEvidence : ModelObject
41{
42 private string _ruleCode =
43 string.Empty;
44
45 private string _featureCode =
46 string.Empty;
47
48 private string _description =
49 string.Empty;
50
51 private string _expectedValue =
52 string.Empty;
53
54 private string _observedValue =
55 string.Empty;
56
57 private bool _isSatisfied;
58 private bool _isRequired = true;
59 private double _weight = 1.0;
60
61 private string _comment =
62 string.Empty;
63
64 /// <summary>
65 /// Initializes an empty classification-evidence object.
66 /// </summary>
67 /// <remarks>
68 /// This constructor is required for XML serialization.
69 /// </remarks>
71 {
72 }
73
74 /// <summary>
75 /// Initializes a classification-evidence object.
76 /// </summary>
77 /// <param name="featureCode">
78 /// Stable code identifying the evaluated feature.
79 /// </param>
80 /// <param name="expectedValue">
81 /// Value expected by the known problem-family rule.
82 /// </param>
83 /// <param name="observedValue">
84 /// Value observed in the analyzed instance.
85 /// </param>
86 /// <param name="isSatisfied">
87 /// Value indicating whether the expected condition
88 /// is satisfied.
89 /// </param>
90 /// <param name="isRequired">
91 /// Value indicating whether failure of this condition
92 /// prevents a direct match.
93 /// </param>
94 /// <param name="description">
95 /// Optional human-readable description of the evaluated
96 /// condition.
97 /// </param>
98 /// <exception cref="ArgumentException">
99 /// Thrown when <paramref name="featureCode"/> is null,
100 /// empty or composed only of white-space characters.
101 /// </exception>
103 string featureCode,
104 string expectedValue,
105 string observedValue,
106 bool isSatisfied,
107 bool isRequired = true,
108 string description = "")
109 {
110 if (string.IsNullOrWhiteSpace(featureCode))
111 {
112 throw new ArgumentException(
113 "A classification feature code is required.",
114 nameof(featureCode));
115 }
116
117 FeatureCode = featureCode;
118
120 expectedValue;
121
123 observedValue;
124
126 isSatisfied;
127
128 IsRequired =
129 isRequired;
130
132 description;
133 }
134
135 /// <summary>
136 /// Gets or sets an optional stable identifier for the
137 /// classification rule that produced this evidence.
138 /// </summary>
139 /// <remarks>
140 /// A rule code is useful when several conditions evaluate
141 /// the same feature.
142 ///
143 /// Examples include:
144 /// <c>LSU.ITEM_COUNT</c> and
145 /// <c>CLSP.MULTI_ITEM</c>.
146 /// </remarks>
147 [XmlAttribute("ruleCode")]
148 public string RuleCode
149 {
150 get => _ruleCode;
151 set
152 {
153 if (SetProperty(
154 ref _ruleCode,
155 value?.Trim() ?? string.Empty))
156 {
157 OnPropertyChanged(
158 nameof(HasRuleCode));
159 }
160 }
161 }
162
163 /// <summary>
164 /// Gets or sets the stable code of the feature that
165 /// was evaluated.
166 /// </summary>
167 /// <remarks>
168 /// The code should normally correspond to a property of
169 /// <see cref="LotSizingProblemFeatures"/>.
170 ///
171 /// Examples include:
172 /// <c>itemCount</c>,
173 /// <c>isMultiLevel</c>,
174 /// <c>isCapacitated</c> and
175 /// <c>hasTransportation</c>.
176 /// </remarks>
177 [XmlAttribute("featureCode")]
178 public string FeatureCode
179 {
180 get => _featureCode;
181 set => SetProperty(
182 ref _featureCode,
183 value?.Trim() ?? string.Empty);
184 }
185
186 /// <summary>
187 /// Gets or sets a human-readable description of the
188 /// evaluated condition.
189 /// </summary>
190 /// <remarks>
191 /// This text is intended for reports and user interfaces.
192 /// The stable programmatic identifier remains
193 /// <see cref="FeatureCode"/>.
194 /// </remarks>
195 [XmlElement("description")]
196 public string Description
197 {
198 get => _description;
199 set => SetProperty(
200 ref _description,
201 value?.Trim() ?? string.Empty);
202 }
203
204 /// <summary>
205 /// Gets or sets the value expected by the known
206 /// problem-family rule.
207 /// </summary>
208 /// <remarks>
209 /// The value is stored as text so that the evidence can
210 /// represent Boolean, numerical, textual and enumeration
211 /// conditions without depending on a specific condition
212 /// implementation.
213 /// </remarks>
214 [XmlElement("expectedValue")]
215 public string ExpectedValue
216 {
217 get => _expectedValue;
218 set => SetProperty(
219 ref _expectedValue,
220 value?.Trim() ?? string.Empty);
221 }
222
223 /// <summary>
224 /// Gets or sets the value observed in the analyzed
225 /// lot-sizing instance.
226 /// </summary>
227 [XmlElement("observedValue")]
228 public string ObservedValue
229 {
230 get => _observedValue;
231 set => SetProperty(
232 ref _observedValue,
233 value?.Trim() ?? string.Empty);
234 }
235
236 /// <summary>
237 /// Gets or sets a value indicating whether the observed
238 /// feature satisfies the expected condition.
239 /// </summary>
240 [XmlAttribute("satisfied")]
241 public bool IsSatisfied
242 {
243 get => _isSatisfied;
244 set
245 {
246 if (SetProperty(
247 ref _isSatisfied,
248 value))
249 {
250 NotifyDerivedProperties();
251 }
252 }
253 }
254
255 /// <summary>
256 /// Gets or sets a value indicating whether the evaluated
257 /// condition is mandatory for a direct match.
258 /// </summary>
259 /// <remarks>
260 /// An unsatisfied required condition normally prevents
261 /// an exact match.
262 ///
263 /// An unsatisfied optional condition may instead identify
264 /// an extension, an additional feature or a difference
265 /// that does not invalidate the underlying family.
266 /// </remarks>
267 [XmlAttribute("required")]
268 public bool IsRequired
269 {
270 get => _isRequired;
271 set
272 {
273 if (SetProperty(
274 ref _isRequired,
275 value))
276 {
277 NotifyDerivedProperties();
278 }
279 }
280 }
281
282 /// <summary>
283 /// Gets or sets the relative importance assigned to this
284 /// evidence during approximate matching.
285 /// </summary>
286 /// <remarks>
287 /// A weight of zero means that the evidence is recorded
288 /// for information only.
289 ///
290 /// Required conditions remain required regardless of
291 /// their weight.
292 /// </remarks>
293 /// <exception cref="ArgumentOutOfRangeException">
294 /// Thrown when the supplied value is negative, not finite
295 /// or not a number.
296 /// </exception>
297 [XmlAttribute("weight")]
298 public double Weight
299 {
300 get => _weight;
301 set
302 {
303 if (!double.IsFinite(value) ||
304 value < 0.0)
305 {
306 throw new ArgumentOutOfRangeException(
307 nameof(value),
308 value,
309 "The evidence weight must be finite " +
310 "and non-negative.");
311 }
312
313 SetProperty(
314 ref _weight,
315 value);
316 }
317 }
318
319 /// <summary>
320 /// Gets or sets an optional explanatory comment about
321 /// the evidence.
322 /// </summary>
323 /// <remarks>
324 /// The comment may describe how the observed value was
325 /// extracted or why an unsatisfied condition is treated
326 /// as an accepted extension.
327 /// </remarks>
328 [XmlElement("comment")]
329 public string Comment
330 {
331 get => _comment;
332 set
333 {
334 if (SetProperty(
335 ref _comment,
336 value?.Trim() ?? string.Empty))
337 {
338 OnPropertyChanged(
339 nameof(HasComment));
340 }
341 }
342 }
343
344 /// <summary>
345 /// Gets a value indicating whether a classification-rule
346 /// code has been recorded.
347 /// </summary>
348 [XmlIgnore]
349 public bool HasRuleCode =>
350 !string.IsNullOrWhiteSpace(
351 RuleCode);
352
353 /// <summary>
354 /// Gets a value indicating whether an explanatory comment
355 /// has been recorded.
356 /// </summary>
357 [XmlIgnore]
358 public bool HasComment =>
359 !string.IsNullOrWhiteSpace(
360 Comment);
361
362 /// <summary>
363 /// Gets a value indicating whether this evidence supports
364 /// the evaluated problem-family match.
365 /// </summary>
366 [XmlIgnore]
367 public bool SupportsMatch =>
369
370 /// <summary>
371 /// Gets a value indicating whether a required condition
372 /// is not satisfied.
373 /// </summary>
374 /// <remarks>
375 /// A blocking mismatch normally prevents an exact or
376 /// direct match with the evaluated problem family.
377 /// </remarks>
378 [XmlIgnore]
379 public bool IsBlockingMismatch =>
380 IsRequired &&
382
383 /// <summary>
384 /// Gets a value indicating whether an optional condition
385 /// is not satisfied.
386 /// </summary>
387 /// <remarks>
388 /// An optional mismatch may identify a known extension
389 /// or an additional feature of the complete problem.
390 /// </remarks>
391 [XmlIgnore]
392 public bool IsOptionalMismatch =>
393 !IsRequired &&
395
396 /// <inheritdoc/>
397 public override string ToString()
398 {
399 string result =
401 ? "satisfied"
402 : "not satisfied";
403
404 string requirement =
406 ? "required"
407 : "optional";
408
409 return
410 $"{FeatureCode}: expected " +
411 $"'{ExpectedValue}', observed " +
412 $"'{ObservedValue}' — {result}, " +
413 $"{requirement}";
414 }
415
416 private void NotifyDerivedProperties()
417 {
418 OnPropertyChanged(
419 nameof(SupportsMatch));
420
421 OnPropertyChanged(
422 nameof(IsBlockingMismatch));
423
424 OnPropertyChanged(
425 nameof(IsOptionalMismatch));
426 }
427}
bool IsRequired
Gets or sets a value indicating whether the evaluated condition is mandatory for a direct match.
bool IsSatisfied
Gets or sets a value indicating whether the observed feature satisfies the expected condition.
double Weight
Gets or sets the relative importance assigned to this evidence during approximate matching.
string Comment
Gets or sets an optional explanatory comment about the evidence.
string RuleCode
Gets or sets an optional stable identifier for the classification rule that produced this evidence.
bool IsBlockingMismatch
Gets a value indicating whether a required condition is not satisfied.
bool HasRuleCode
Gets a value indicating whether a classification-rule code has been recorded.
ClassificationEvidence(string featureCode, string expectedValue, string observedValue, bool isSatisfied, bool isRequired=true, string description="")
Initializes a classification-evidence object.
bool HasComment
Gets a value indicating whether an explanatory comment has been recorded.
string ExpectedValue
Gets or sets the value expected by the known problem-family rule.
string FeatureCode
Gets or sets the stable code of the feature that was evaluated.
string ObservedValue
Gets or sets the value observed in the analyzed lot-sizing instance.
bool IsOptionalMismatch
Gets a value indicating whether an optional condition is not satisfied.
ClassificationEvidence()
Initializes an empty classification-evidence object.
bool SupportsMatch
Gets a value indicating whether this evidence supports the evaluated problem-family match.
string Description
Gets or sets a human-readable description of the evaluated condition.