2using System.Collections.Generic;
3using System.Globalization;
5using System.Xml.Serialization;
6using LotSizingDataModel.Core.Common;
8using LotSizingDataModel.Solution;
9using LotSizingDataModel.Solution.Common;
49[XmlType(TypeName =
"knownResult")]
52 private string _resultId =
55 private string _name =
58 private double? _reportedObjectiveValue;
60 private string _objectiveName =
63 private string _objectiveUnit =
80 private LotSizingSolution? _detailedSolution;
82 private string _methodName =
85 private string _sourceTitle =
88 private string _sourceReference =
91 private string _sourceUri =
94 private string _digitalObjectIdentifier =
97 private DateTime? _obtainedAtUtc;
99 private DateTime? _recordedAtUtc;
101 private string _supplyChainFingerprint =
104 private string _supersededByResultId =
107 private string _comment =
133 if (
string.IsNullOrWhiteSpace(resultId))
135 throw new ArgumentException(
136 "A known-result identifier is required.",
167 double reportedObjectiveValue,
172 reportedObjectiveValue;
186 [XmlAttribute(
"resultId")]
194 value?.Trim() ??
string.Empty))
196 NotifyIdentityProperties();
209 [XmlAttribute(
"name")]
217 value?.Trim() ??
string.Empty))
241 "reportedObjectiveValue",
245 get => _reportedObjectiveValue;
248 if (value.HasValue &&
249 !
double.IsFinite(value.Value))
251 throw new ArgumentOutOfRangeException(
254 "The reported objective value must " +
259 ref _reportedObjectiveValue,
262 NotifyResultDataProperties();
277 [XmlAttribute(
"objectiveName")]
280 get => _objectiveName;
285 value?.Trim() ??
string.Empty))
301 [XmlAttribute(
"objectiveUnit")]
304 get => _objectiveUnit;
309 value?.Trim() ??
string.Empty))
331 [XmlAttribute(
"feasibilityStatus")]
334 get => _feasibilityStatus;
338 ref _feasibilityStatus,
358 [XmlAttribute(
"optimalityStatus")]
361 get => _optimalityStatus;
365 ref _optimalityStatus,
378 [XmlAttribute(
"verificationStatus")]
381 get => _verificationStatus;
385 ref _verificationStatus,
388 NotifyVerificationProperties();
411 get => _detailedSolution;
415 ref _detailedSolution,
418 NotifyResultDataProperties();
432 [XmlElement(
"methodName")]
440 value?.Trim() ??
string.Empty))
452 [XmlElement(
"sourceTitle")]
460 value?.Trim() ??
string.Empty))
462 NotifySourceProperties();
476 [XmlElement(
"sourceReference")]
479 get => _sourceReference;
483 ref _sourceReference,
484 value?.Trim() ??
string.Empty))
486 NotifySourceProperties();
500 [XmlElement(
"sourceUri")]
508 value?.Trim() ??
string.Empty))
510 NotifySourceProperties();
523 [XmlAttribute(
"doi")]
526 get => _digitalObjectIdentifier;
530 ref _digitalObjectIdentifier,
531 NormalizeDigitalObjectIdentifier(value)))
533 NotifySourceProperties();
546 [XmlArray(
"discoverers")]
547 [XmlArrayItem(
"discoverer")]
555 [XmlArray(
"sourceAuthors")]
556 [XmlArrayItem(
"author")]
576 get => _obtainedAtUtc;
577 set => SetUtcDateTime(
592 get => _recordedAtUtc;
593 set => SetUtcDateTime(
608 [XmlAttribute(
"supplyChainFingerprint")]
611 get => _supplyChainFingerprint;
615 ref _supplyChainFingerprint,
616 value?.Trim() ??
string.Empty))
635 [XmlAttribute(
"supersededByResultId")]
638 get => _supersededByResultId;
642 ref _supersededByResultId,
643 value?.Trim() ??
string.Empty))
645 NotifyVerificationProperties();
654 [XmlElement(
"comment")]
662 value?.Trim() ??
string.Empty))
676 !
string.IsNullOrWhiteSpace(
ResultId);
684 !
string.IsNullOrWhiteSpace(
Name);
720 !EqualityComparer<FeasibilityStatus>
736 !EqualityComparer<OptimalityStatus>
767 !
string.IsNullOrWhiteSpace(
785 !
string.IsNullOrWhiteSpace(
794 !
string.IsNullOrWhiteSpace(
Comment);
802 !
string.IsNullOrWhiteSpace(
857 IEnumerable<string> discoverers)
859 ReplaceNormalizedStrings(
862 nameof(discoverers));
879 IEnumerable<string> sourceAuthors)
881 ReplaceNormalizedStrings(
884 nameof(sourceAuthors));
932 if (
string.IsNullOrWhiteSpace(newResultId))
934 throw new ArgumentException(
935 "A superseding result identifier is required.",
936 nameof(newResultId));
939 string normalizedResultId =
945 StringComparison.OrdinalIgnoreCase))
947 throw new ArgumentException(
948 "A result cannot supersede itself.",
949 nameof(newResultId));
978 string currentFingerprint)
981 string.IsNullOrWhiteSpace(currentFingerprint))
986 return string.Equals(
988 currentFingerprint.Trim(),
989 StringComparison.Ordinal);
996 string resultDescription =
1001 string objectiveDescription =
1004 double objectiveValue =>
1005 objectiveValue.ToString(
1006 CultureInfo.InvariantCulture),
1009 "detailed solution",
1016 $
"{resultDescription}; " +
1017 $
"{objectiveDescription}; " +
1018 $
"{VerificationStatus}";
1021 private static string
1022 NormalizeDigitalObjectIdentifier(
1025 string normalizedValue =
1029 const string httpsPrefix =
1032 const string httpPrefix =
1035 const string doiPrefix =
1038 if (normalizedValue.StartsWith(
1040 StringComparison.OrdinalIgnoreCase))
1042 return normalizedValue[
1043 httpsPrefix.Length..].Trim();
1046 if (normalizedValue.StartsWith(
1048 StringComparison.OrdinalIgnoreCase))
1050 return normalizedValue[
1051 httpPrefix.Length..].Trim();
1054 if (normalizedValue.StartsWith(
1056 StringComparison.OrdinalIgnoreCase))
1058 return normalizedValue[
1059 doiPrefix.Length..].Trim();
1062 return normalizedValue;
1065 private static void ReplaceNormalizedStrings(
1066 ICollection<string> destination,
1067 IEnumerable<string> source,
1068 string parameterName)
1070 ArgumentNullException.ThrowIfNull(source);
1072 string[] normalizedValues =
1076 !
string.IsNullOrWhiteSpace(value))
1081 StringComparer.OrdinalIgnoreCase)
1085 StringComparer.OrdinalIgnoreCase)
1088 destination.Clear();
1090 foreach (
string value
in normalizedValues)
1092 destination.Add(value);
1096 private static DateTime ConvertToUtc(
1099 return value.Kind
switch
1104 DateTimeKind.Local =>
1105 value.ToUniversalTime(),
1108 DateTime.SpecifyKind(
1114 private void SetUtcDateTime(
1115 ref DateTime? storage,
1117 string propertyName)
1119 DateTime? normalizedValue =
1121 ? ConvertToUtc(value.Value)
1130 private void NotifyIdentityProperties()
1139 private void NotifyResultDataProperties()
1154 private void NotifySourceProperties()
1160 private void NotifyVerificationProperties()
string SourceUri
Gets or sets an optional URI identifying the source from which the result was obtained.
KnownResult()
Initializes an empty known result.
List< string > Discoverers
Gets the names of persons or organizations credited with obtaining or discovering the result.
DateTime? RecordedAtUtc
Gets or sets the UTC date and time at which the result was recorded in the instance data.
bool CanBeSelectedAsBestKnownResult
Gets a value indicating whether this result may be considered when selecting the best known result.
bool HasObjectiveUnit
Gets a value indicating whether the objective unit has been recorded.
bool HasFeasibilityInformation
Gets a value indicating whether feasibility information has been recorded.
bool MatchesSupplyChainFingerprint(string currentFingerprint)
Determines whether this result was obtained for the supplied supply-chain fingerprint.
void ClearSupersedingResult()
Removes the link indicating that this result has been superseded.
OptimalityStatus OptimalityStatus
Gets or sets the reported or verified optimality status of the result.
override string ToString()
LotSizingSolution? DetailedSolution
Gets or sets the optional detailed solution associated with this known result.
string Name
Gets or sets the human-readable name of the result.
void ClearDetailedSolution()
Removes the detailed solution while preserving all reported objective and source information.
bool HasReportedObjectiveValue
Gets a value indicating whether an explicit objective value has been reported.
bool HasObjectiveName
Gets a value indicating whether the objective name has been recorded.
string ResultId
Gets or sets the stable identifier of this result.
bool HasOptimalityInformation
Gets a value indicating whether optimality information has been recorded.
KnownResultVerificationStatus VerificationStatus
Gets or sets the level of verification applied to this result.
List< string > SourceAuthors
Gets the authors or organizations associated with the source reporting the result.
string MethodName
Gets or sets the name of the algorithm, solver or procedure that produced the result.
string SourceTitle
Gets or sets the title of the publication, report, repository or other source reporting the result.
void ReplaceDiscoverers(IEnumerable< string > discoverers)
Replaces the persons or organizations credited with discovering or obtaining the result.
bool IsInvalidated
Gets a value indicating whether the result has been invalidated.
bool HasDiscoverers
Gets a value indicating whether at least one discoverer has been recorded.
string SupersededByResultId
Gets or sets the identifier of a newer result that supersedes this result.
string ObjectiveName
Gets or sets the name of the reported objective.
bool HasSupplyChainFingerprint
Gets a value indicating whether a supply-chain fingerprint has been recorded.
void MarkAsSupersededBy(string newResultId)
Marks this result as superseded by another result.
FeasibilityStatus FeasibilityStatus
Gets or sets the reported or verified feasibility status of the result.
string DigitalObjectIdentifier
Gets or sets the digital object identifier of the publication reporting the result.
bool HasMethodInformation
Gets a value indicating whether information about the solution method has been recorded.
bool HasResultData
Gets a value indicating whether the result contains usable numerical or detailed solution data.
DateTime? ObtainedAtUtc
Gets or sets the UTC date and time at which the result was obtained.
string SupplyChainFingerprint
Gets or sets the fingerprint of the supply-chain data to which this result applies.
KnownResult(string resultId)
Initializes a known result with a stable identifier.
bool HasSourceInformation
Gets a value indicating whether at least one source field has been recorded.
double? ReportedObjectiveValue
Gets or sets the objective value explicitly reported for this result.
KnownResult(string resultId, double reportedObjectiveValue, string name="")
Initializes a known result containing a reported objective value.
void ClearReportedObjective()
Removes the explicitly reported objective value and its descriptive metadata.
string Comment
Gets or sets an optional explanatory comment about the result, its source or its verification.
bool HasComment
Gets a value indicating whether an explanatory comment has been recorded.
bool IsSuperseded
Gets a value indicating whether this result has been superseded by another result.
string SourceReference
Gets or sets a bibliographic or documentary reference for the source reporting the result.
string ObjectiveUnit
Gets or sets the unit associated with the reported objective value.
bool HasName
Gets a value indicating whether the result has a human-readable name.
bool HasDetailedSolution
Gets a value indicating whether a detailed solution is associated with the result.
void ReplaceSourceAuthors(IEnumerable< string > sourceAuthors)
Replaces the authors or organizations associated with the result source.
bool HasResultId
Gets a value indicating whether the result has a stable identifier.
bool IsDisputed
Gets a value indicating whether the result has been disputed.
KnownResultVerificationStatus
Indicates the level of verification associated with a known result for a lot-sizing problem instance.