1using System.Globalization;
15 private static readonly CultureInfo ReportCulture =
16 CultureInfo.InvariantCulture;
21 string? candidateName =
null,
24 ArgumentNullException.ThrowIfNull(result);
29 options.EnsureValid();
37 builder.AppendLine(
"Lot-sizing solution check");
38 builder.AppendLine(
new string(
'=', 50));
40 if (!
string.IsNullOrWhiteSpace(candidateName))
42 builder.Append(
"Candidate : ");
43 builder.AppendLine(candidateName);
46 builder.Append(
"Result : ");
51 builder.Append(
"Level : ");
52 builder.AppendLine(summary.
Level.ToString());
53 builder.Append(
"Issues : ");
55 builder.Append(
" (errors=");
57 builder.Append(
", warnings=");
59 builder.Append(
", information=");
61 builder.AppendLine(
")");
63 if (options.IncludeStageDetails)
65 AppendStages(builder, summary);
68 if (options.IncludeFeasibilityMetrics &&
72 AppendFeasibility(builder, summary);
75 if (options.IncludeObjectiveMetrics &&
79 AppendObjective(builder, summary);
97 ArgumentNullException.ThrowIfNull(summary);
102 options.EnsureValid();
107 builder.AppendLine(
"Lot-sizing solution-check batch");
108 builder.AppendLine(
new string(
'=', 50));
109 builder.Append(
"Candidates : ");
110 builder.AppendLine(summary.
CandidateCount.ToString(ReportCulture));
111 builder.Append(
"Valid : ");
113 builder.Append(
"Invalid : ");
115 builder.Append(
"Errors : ");
116 builder.AppendLine(summary.
ErrorCount.ToString(ReportCulture));
117 builder.Append(
"Warnings : ");
118 builder.AppendLine(summary.
WarningCount.ToString(ReportCulture));
119 builder.Append(
"Information: ");
121 builder.Append(
"With constraint violations : ");
124 .ToString(ReportCulture));
125 builder.Append(
"With objective mismatch : ");
128 .ToString(ReportCulture));
129 builder.Append(
"Maximum constraint violation: ");
135 builder.AppendLine();
136 builder.AppendLine(
"Issue categories");
137 builder.AppendLine(
"----------------");
141 .OrderByDescending(item => item.Count)
142 .ThenBy(item => item.Kind))
145 builder.Append(issueCount.
Kind);
146 builder.Append(
" : ");
148 issueCount.
Count.ToString(ReportCulture));
152 if (summary.
Items.Count > 0)
154 builder.AppendLine();
155 builder.AppendLine(
"Candidates");
156 builder.AppendLine(
"----------");
170 builder.Append(
" - ");
174 builder.Append(
" errors=");
176 builder.Append(
" warnings=");
181 builder.Append(
" violatedConstraints=");
189 builder.Append(
" objectiveMismatch=true");
192 builder.AppendLine();
201 private static void AppendStages(
202 StringBuilder builder,
205 builder.AppendLine();
206 builder.AppendLine(
"Stages");
207 builder.AppendLine(
"------");
214 private static void AppendStage(
215 StringBuilder builder,
220 builder.Append(name.PadRight(18));
221 builder.Append(
" : ");
222 builder.AppendLine(FormatStageStatus(status));
225 private static string FormatStageStatus(
243 private static void AppendFeasibility(
244 StringBuilder builder,
245 SolutionCheckSummary summary)
247 builder.AppendLine();
248 builder.AppendLine(
"Feasibility metrics");
249 builder.AppendLine(
"-------------------");
250 builder.Append(
" Violated constraints : ");
252 summary.ViolatedConstraintCount.ToString(ReportCulture));
253 builder.Append(
" Maximum violation : ");
255 FormatDouble(summary.MaximumConstraintViolation));
256 builder.Append(
" Total violation : ");
258 FormatDouble(summary.TotalConstraintViolation));
261 private static void AppendObjective(
262 StringBuilder builder,
263 SolutionCheckSummary summary)
265 builder.AppendLine();
266 builder.AppendLine(
"Objective metrics");
267 builder.AppendLine(
"-----------------");
268 AppendNullableDouble(
270 "Reported objective",
271 summary.ReportedObjectiveValue);
272 AppendNullableDouble(
274 "Recomputed objective",
275 summary.RecomputedObjectiveValue);
276 AppendNullableDouble(
278 "Absolute difference",
279 summary.ObjectiveDifference);
280 AppendNullableDouble(
282 "Relative difference",
283 summary.ObjectiveRelativeDifference);
284 AppendNullableDouble(
286 "Comparison tolerance",
287 summary.ObjectiveComparisonTolerance);
290 private static void AppendNullableDouble(
291 StringBuilder builder,
296 builder.Append(label.PadRight(24));
297 builder.Append(
" : ");
300 ? FormatDouble(value.Value)
304 private static void AppendIssues(
305 StringBuilder builder,
306 SolutionCheckResult result,
307 SolutionCheckReportOptions options)
309 IEnumerable<SolutionCheckIssue> issues =
316 if (options.SortIssuesBySeverity)
320 .OrderByDescending(issue => issue.Severity)
321 .ThenBy(issue => issue.Kind)
322 .ThenBy(issue => issue.DomainKey ??
string.Empty)
323 .ThenBy(issue => issue.ConstraintName ??
string.Empty)
324 .ThenBy(issue => issue.Message);
327 List<SolutionCheckIssue> materializedIssues =
330 if (materializedIssues.Count == 0)
336 options.MaximumDetailedIssues == 0
337 ? materializedIssues.Count
339 options.MaximumDetailedIssues,
340 materializedIssues.Count);
342 builder.AppendLine();
343 builder.Append(
"Diagnostics (");
344 builder.Append(materializedIssues.Count);
345 builder.AppendLine(
")");
346 builder.AppendLine(
"-----------");
349 index < displayedCount;
354 materializedIssues[index]);
358 materializedIssues.Count - displayedCount;
360 if (omittedCount > 0)
362 builder.Append(
" ... ");
363 builder.Append(omittedCount);
364 builder.AppendLine(
" additional diagnostic(s) omitted.");
368 private static bool ShouldIncludeIssue(
369 SolutionCheckIssue issue,
370 SolutionCheckReportOptions options)
372 return issue.Severity
switch
374 SolutionCheckSeverity.Information =>
375 options.IncludeInformationIssues,
376 SolutionCheckSeverity.Warning =>
377 options.IncludeWarningIssues,
378 SolutionCheckSeverity.Error =>
379 options.IncludeErrorIssues,
385 private static void AppendIssue(
386 StringBuilder builder,
387 SolutionCheckIssue issue)
389 builder.Append(
" [");
390 builder.Append(issue.
Severity.ToString().ToUpperInvariant());
391 builder.Append(
"][");
392 builder.Append(issue.
Kind);
393 builder.Append(
"] ");
396 if (!
string.IsNullOrWhiteSpace(issue.
DomainKey))
398 builder.Append(
" | domain=");
404 builder.Append(
" | constraint=");
410 builder.Append(
" | actual=");
411 builder.Append(FormatDouble(issue.
ActualValue.Value));
416 builder.Append(
" | expected=");
422 builder.Append(
" | violation=");
423 builder.Append(FormatDouble(issue.
Violation.Value));
426 builder.AppendLine();
429 private static string FormatDouble(
432 return value.ToString(
Associates a batch candidate identifier with its compact checker summary.
string CandidateKey
Gets or sets the caller-defined candidate identifier.
SolutionCheckSummary Summary
Gets or sets the compact checker summary for this candidate.
string? CandidateName
Gets or sets an optional human-readable candidate name.
Contains aggregated metrics for a collection of checked solutions.
int CandidateWithObjectiveMismatchCount
Gets or sets the number of candidates for which objective checking completed and detected an inconsis...
int ErrorCount
Gets or sets the total number of errors.
int ValidCandidateCount
Gets or sets the number of candidates that passed all requested checks.
int WarningCount
Gets or sets the total number of warnings.
int InvalidCandidateCount
Gets or sets the number of candidates that did not pass all requested checks.
List< SolutionCheckBatchItemSummary > Items
Gets or sets the per-candidate summaries in insertion order.
List< SolutionCheckIssueCount > IssueCountsByKind
Gets or sets issue counts aggregated by category.
double MaximumConstraintViolation
Gets or sets the largest constraint violation observed in the batch.
int CandidateWithConstraintViolationCount
Gets or sets the number of candidates with at least one violated mathematical constraint.
int InformationCount
Gets or sets the total number of informational diagnostics.
int CandidateCount
Gets or sets the number of candidates represented by the summary.
Associates an issue category with its occurrence count.
int Count
Gets or sets the number of issues in this category.
SolutionCheckIssueKind Kind
Gets or sets the issue category.
Configures human-readable checker reports.
Builds compact summaries from complete checker results.
static SolutionCheckSummary Create(SolutionCheckResult result)
Creates a compact machine-oriented summary.
Provides a compact machine-oriented summary of one solution check.
SolutionCheckLevel Level
Gets or sets the checking level requested for the candidate.
SolutionCheckStageStatus ObjectiveStatus
Gets or sets the objective-check-stage status.
int InformationCount
Gets or sets the number of informational diagnostics.
SolutionCheckStageStatus StructuralStatus
Gets or sets the structural-stage status.
int ErrorCount
Gets or sets the number of error diagnostics.
int IssueCount
Gets or sets the total number of diagnostics.
int ViolatedConstraintCount
Gets or sets the number of violated mathematical constraints.
int WarningCount
Gets or sets the number of warning diagnostics.
SolutionCheckStageStatus FeasibilityStatus
Gets or sets the mathematical-feasibility-stage status.
bool IsValid
Gets or sets whether every requested check passed.
SolutionCheckStageStatus VariableDomainStatus
Gets or sets the variable-domain-stage status.
Produces deterministic plain-text reports for checker results.
string Format(SolutionCheckResult result, string? candidateName=null, SolutionCheckReportOptions? options=null)
Formats one checker result.A deterministic human-readable report.
string FormatBatch(SolutionCheckBatchSummary summary, SolutionCheckReportOptions? options=null)
Formats an aggregated batch summary.A deterministic human-readable batch report.
SolutionCheckIssueKind Kind
Gets or sets the issue category.
string? DomainKey
Gets or sets the related mathematical-domain key, when available.
SolutionCheckSeverity Severity
Gets or sets the issue severity.
double? Violation
Gets or sets the numerical violation magnitude, when meaningful.
double? ActualValue
Gets or sets the actual value involved in the issue, when meaningful.
double? ExpectedValue
Gets or sets an expected or reference value, when meaningful.
string? ConstraintName
Gets or sets the related mathematical constraint name, when available.
string Message
Gets or sets a human-readable diagnostic message.
Contains the complete result of checking one lot-sizing solution.
IReadOnlyList< SolutionCheckIssue > Issues
Gets all checker diagnostics.
SolutionCheckStageStatus
Describes the execution and outcome of one logical checker stage.
@ Passed
The stage completed and its checked conditions were satisfied.
@ NotCompleted
The stage was requested but could not be executed to completion.
@ NotRequested
The stage was not requested by the selected checking level.
@ Failed
The stage completed and at least one checked condition failed.