LotSizingDataModel.Solver 2.0.1
Solver-independent modeling, execution, monitoring and adapter infrastructure.
Loading...
Searching...
No Matches
MathematicalModelSolverPluginBase.cs
Go to the documentation of this file.
1using System;
2using System.Collections.Generic;
3using System.Linq;
4using System.Threading;
5using System.Threading.Tasks;
11
13
14/// <summary>
15/// Provides the common plugin contract shared by native
16/// mathematical-model solver adapters.
17/// </summary>
18/// <remarks>
19/// <para>
20/// The class combines the dynamically discoverable
21/// <see cref="ISolverAdapter"/> contract with the
22/// solver-independent mathematical-model execution implemented
23/// by <see cref="MathematicalModelSolverAdapterBase"/>.
24/// </para>
25/// <para>
26/// Native plugins should derive from this class and implement
27/// availability checking plus the native mathematical-model
28/// translation and optimization logic.
29/// </para>
30/// <para>
31/// High-level lot-sizing-instance orchestration remains the
32/// responsibility of <see cref="LotSizingSolverService"/>.
33/// Native plugins must not rebuild lot-sizing equations.
34/// </para>
35/// </remarks>
36public abstract class MathematicalModelSolverPluginBase :
39{
40 private readonly IReadOnlyCollection<SolverCapability>
41 _capabilities;
42
43 /// <summary>
44 /// Initializes the plugin base with its declared
45 /// capabilities.
46 /// </summary>
47 /// <param name="capabilities">
48 /// Solver capabilities implemented by the plugin.
49 /// </param>
50 /// <exception cref="ArgumentNullException">
51 /// Thrown when <paramref name="capabilities"/> is
52 /// <see langword="null"/>.
53 /// </exception>
54 /// <exception cref="InvalidOperationException">
55 /// Thrown when the collection contains
56 /// <see cref="SolverCapability.Unknown"/>.
57 /// </exception>
59 IEnumerable<SolverCapability> capabilities)
60 {
61 ArgumentNullException.ThrowIfNull(
62 capabilities);
63
64 SolverCapability[] normalizedCapabilities =
65 capabilities
66 .Distinct()
67 .ToArray();
68
69 if (normalizedCapabilities.Contains(
70 SolverCapability.Unknown))
71 {
72 throw new InvalidOperationException(
73 "A solver plugin cannot declare the Unknown " +
74 "capability.");
75 }
76
77 _capabilities =
78 Array.AsReadOnly(
79 normalizedCapabilities);
80 }
81
82 /// <summary>
83 /// Occurs when a new solver progress snapshot is available.
84 /// </summary>
85 public event EventHandler<SolverProgressEventArgs>?
87
88 /// <summary>
89 /// Gets the unique adapter identifier.
90 /// </summary>
91 public abstract string AdapterId
92 {
93 get;
94 }
95
96 /// <summary>
97 /// Gets the adapter display name.
98 /// </summary>
99 public abstract string AdapterName
100 {
101 get;
102 }
103
104 /// <summary>
105 /// Gets the adapter implementation version.
106 /// </summary>
107 public abstract string AdapterVersion
108 {
109 get;
110 }
111
112 /// <summary>
113 /// Gets the minimum supported native solver version.
114 /// </summary>
115 public abstract string MinimumSupportedSolverVersion
116 {
117 get;
118 }
119
120 /// <summary>
121 /// Gets the capabilities implemented by this plugin.
122 /// </summary>
123 public IReadOnlyCollection<SolverCapability> Capabilities =>
124 _capabilities;
125
126 /// <summary>
127 /// Gets a value indicating whether the plugin supports the
128 /// specified capability.
129 /// </summary>
130 /// <param name="capability">
131 /// Capability to test.
132 /// </param>
133 /// <returns>
134 /// <see langword="true"/> when the capability is declared;
135 /// otherwise, <see langword="false"/>.
136 /// </returns>
138 SolverCapability capability)
139 {
140 return _capabilities.Contains(
141 capability);
142 }
143
144 /// <summary>
145 /// Checks whether the native solver is installed, loadable,
146 /// and licensed when a license is required.
147 /// </summary>
148 /// <param name="cancellationToken">
149 /// Token used to cancel the availability check.
150 /// </param>
151 /// <returns>
152 /// Native solver availability information.
153 /// </returns>
154 public abstract ValueTask<SolverAvailabilityInfo>
156 CancellationToken cancellationToken = default);
157
158 /// <summary>
159 /// Rejects direct high-level instance solving through the
160 /// plugin.
161 /// </summary>
162 /// <remarks>
163 /// Native plugins receive an already built mathematical
164 /// model. Applications should use
165 /// <see cref="LotSizingSolverService"/> to build the selected
166 /// formulation, select a plugin, solve the mathematical
167 /// model, and map the solution back to
168 /// LotSizingSolution.
169 /// </remarks>
170 /// <param name="request">
171 /// High-level lot-sizing request.
172 /// </param>
173 /// <param name="cancellationToken">
174 /// Cancellation token.
175 /// </param>
176 /// <returns>
177 /// This method never returns successfully.
178 /// </returns>
179 /// <exception cref="NotSupportedException">
180 /// Always thrown because a native mathematical-model plugin
181 /// must not rebuild lot-sizing formulations.
182 /// </exception>
183 Task<SolverRunResult> ILotSizingSolver.SolveAsync(
184 SolverRequest request,
185 CancellationToken cancellationToken)
186 {
187 ArgumentNullException.ThrowIfNull(
188 request);
189
190 throw new NotSupportedException(
191 $"Adapter '{AdapterName}' executes already-built " +
192 "mathematical models. Use LotSizingSolverService " +
193 "for complete lot-sizing-instance orchestration.");
194 }
195
196 /// <summary>
197 /// Publishes a progress snapshot to the .NET event and all
198 /// observers attached to the mathematical solve request.
199 /// </summary>
200 /// <param name="request">
201 /// Active mathematical-model solve request.
202 /// </param>
203 /// <param name="snapshot">
204 /// Progress snapshot to publish.
205 /// </param>
206 /// <param name="cancellationToken">
207 /// Token observed while notifying observers.
208 /// </param>
209 /// <returns>
210 /// Task representing observer notification.
211 /// </returns>
212 protected async ValueTask PublishProgressAsync(
214 SolverProgressSnapshot snapshot,
215 CancellationToken cancellationToken = default)
216 {
217 ArgumentNullException.ThrowIfNull(
218 request);
219
220 ArgumentNullException.ThrowIfNull(
221 snapshot);
222
223 ProgressChanged?.Invoke(
224 this,
226 snapshot));
227
228 foreach (
230 in request.ProgressObservers)
231 {
232 cancellationToken.ThrowIfCancellationRequested();
233
234 await observer.OnProgressAsync(
235 snapshot,
236 cancellationToken);
237 }
238 }
239}
Provides common execution-state and cancellation handling for solver adapters that solve solver-indep...
bool SupportsCapability(SolverCapability capability)
Gets a value indicating whether the plugin supports the specified capability.
MathematicalModelSolverPluginBase(IEnumerable< SolverCapability > capabilities)
Initializes the plugin base with its declared capabilities.
EventHandler< SolverProgressEventArgs >? ProgressChanged
Occurs when a new solver progress snapshot is available.
string MinimumSupportedSolverVersion
Gets the minimum supported native solver version.
ValueTask< SolverAvailabilityInfo > CheckAvailabilityAsync(CancellationToken cancellationToken=default)
Checks whether the native solver is installed, loadable, and licensed when a license is required.
async ValueTask PublishProgressAsync(MathematicalModelSolveRequest request, SolverProgressSnapshot snapshot, CancellationToken cancellationToken=default)
Publishes a progress snapshot to the .NET event and all observers attached to the mathematical solve ...
IReadOnlyCollection< SolverCapability > Capabilities
Gets the capabilities implemented by this plugin.
Provides solver progress information to .NET event subscribers.
Describes a request to solve an already built, solver-independent mathematical model.
Describes a request to solve a lot-sizing instance.
IList< ISolverProgressObserver > ProgressObservers
Gets the progress observers attached to this request.
Represents an immutable snapshot of the current progress of a mathematical optimization run.
Defines a dynamically discoverable solver adapter capable of solving solver-independent mathematical ...
Defines the common contract implemented by every lot-sizing solver adapter.
Task< SolverRunResult > SolveAsync(SolverRequest request, CancellationToken cancellationToken=default)
Solves a lot-sizing instance.
Receives progress notifications produced during a solver execution.
ValueTask OnProgressAsync(SolverProgressSnapshot snapshot, CancellationToken cancellationToken=default)
Processes a solver progress snapshot.
SolverCapability
Identifies an optional capability implemented by a solver adapter.