···11default: build check
2233-# Build the Huub solver
33+# Build packages and header files
44build:
55 cargo build
66- cbindgen --config cbindgen_types.toml --crate ipdos-types --output c/ipdos_types.h
77- cbindgen --config cbindgen_template.toml --crate ipdos-solver-template --output c/ipdos_solver_template.c
66+ cbindgen --config cbindgen_types.toml --crate fznso-types --output c/fznso_types.h
77+ cbindgen --config cbindgen_template.toml --crate fznso-solver-template --output c/fznso_solver_template.c
8899# Check the codebase using all CI linters
1010check:
+6-6
README.md
···11-# IPDOS: An Incremental Protocol for Decision and Optimization Solvers
11+# Flat White Vitriol (FZnSO) - An incremental solver protocol for combinatorial solving using shared objects
2233## Introduction
4455## Common Functionality
6677-Although solvers are able to define their own functionality using the IPDOS protocol, we advocate for the following common functionality to be implemented by different solvers.
77+Although solvers are able to define their own functionality using the FZnSO protocol, we advocate for the following common functionality to be implemented by different solvers.
88This will allow for a more consistent user experience when interacting with different solvers.
99Even if a solver does not implement all of these functions, we recommend that the solvers do not use the same name for different functionality.
10101111### Common Options
12121313-A solver will expose its available options through `ipdos_option_list`.
1313+A solver will expose its available options through `fznso_option_list`.
1414We recommend that solvers eagerly implement the following options:
15151616- `all_optimal` (`bool`, default: `false`): If set to `true`, the solver will after finding an optimal solution, continue to search for other solutions with the same objective value.
1717- `fixed_search` (`bool`, default: `false`): If set to `true`, the solver will strictly follow the search order defined by the user.
1818- `intermediate` (`bool`, default: `false`): If set to `true` for a problem with an objective strategy set, the solver will trigger its `on_solution` callback when it finds an intermediate solution.
1919- Afterward, the solver will continue the search until it finds the next solution, or it proves that no better solutions exist (returning the `IpdosComplete` status).
1919+ Afterward, the solver will continue the search until it finds the next solution, or it proves that no better solutions exist (returning the `FznsoComplete` status).
2020- `threads` (`int`, default: `1`): For multithreaded solvers, this option will set the number of threads to use.
2121- `time_limit` (`int`, default: `-1`): If set to a positive integer, the solver will abandon the search after the specified number of milliseconds.
2222- `random_seed` (`opt int`, default: `<>`): If set to a positive integer, the solver will use the given value as the seed for its random number generator.
···25252626### Common Constraints
27272828-A solver will expose the constraints that can be used in a `IpdosModel` through `ipdos_constraint_list`.
2828+A solver will expose the constraints that can be used in a `FznsoModel` through `fznso_constraint_list`.
2929We encourage solvers to support the constraints using the names and definitions from the [FlatZinc Builtins](https://docs.minizinc.dev/en/stable/lib-flatzinc.html).
3030Other MiniZinc (global) constraints are also encouraged to be implemented, using the `fzn_` prefix.
31313232### Common Objective Strategies
33333434-A solver will expose the objective strategies that can be used in a `IpdosModel` through `ipdos_objective_list`.
3434+A solver will expose the objective strategies that can be used in a `FznsoModel` through `fznso_objective_list`.
3535We encourage solvers to support the following objective strategies if possible:
36363737- `lex_maximize_int` (`list of var int`) | `lex_maximize_float` (`list of var float`): The solver will maximize the list of decision variables in lexicographical order, i.e., the first variable is maximized first, then the second variable, etc.
+507
c/fznso_types.h
···11+#ifndef fznso_types_h
22+#define fznso_types_h
33+44+#include <stdbool.h>
55+#include <stdint.h>
66+77+// Representation of the base type of a value.
88+typedef enum FznsoTypeBase {
99+ // Boolean type
1010+ FznsoTypeBaseBool,
1111+ // Integer numeric type
1212+ FznsoTypeBaseInt,
1313+ // Floating point numeric type
1414+ FznsoTypeBaseFloat,
1515+ // Character string type
1616+ FznsoTypeBaseString,
1717+} FznsoTypeBase;
1818+1919+// Enumerated type used to mark the kind of [`FznsoValue`]. This is used to
2020+// determine which "get" method in [`FznsoValueMethods`] is safe to call.
2121+typedef enum FznsoValueKind {
2222+ // No value is available.
2323+ FznsoValueAbsent,
2424+ // The value is available using [`FznsoValueMethods::get_decision`].
2525+ FznsoValueDecision,
2626+ // The value is available using [`FznsoValueMethods::get_constraint`].
2727+ FznsoValueConstraint,
2828+ // The value is available using [`FznsoValueMethods::get_bool`].
2929+ FznsoValueBool,
3030+ // The value is available using [`FznsoValueMethods::get_int`].
3131+ FznsoValueInt,
3232+ // The value is available using [`FznsoValueMethods::get_float`].
3333+ FznsoValueFloat,
3434+ // The value is available using [`FznsoValueMethods::get_string`].
3535+ FznsoValueString,
3636+ // Sets of integers are represented using a range list. The number of
3737+ // ranges is available using [`FznsoValueMethods::len`], and the ranges can
3838+ // be accessed using [`FznsoValueMethods::get_range_int`].
3939+ FznsoValueSetInt,
4040+ // Sets of floats are represented using a range list. The number of
4141+ // ranges is available using [`FznsoValueMethods::len`], and the ranges can
4242+ // be accessed using [`FznsoValueMethods::get_range_float`].
4343+ FznsoValueSetFloat,
4444+ // The length of the list can be accessed using
4545+ // [`FznsoValueMethods::len`], and elements in the list can be
4646+ // accessed using [`FznsoValueMethods::get_element`]
4747+ FznsoValueList,
4848+} FznsoValueKind;
4949+5050+// The status returned by `fznso_solver_run`, indicating whether the solver
5151+// completed its search.
5252+typedef enum FznsoStatus {
5353+ // The solver explored the full search space and yielded all relevant
5454+ // solutions.
5555+ FznsoComplete,
5656+ // The solver did not explore the full search space due to a timeout or
5757+ // other termination condition. Additional (better) solutions might be
5858+ // possible.
5959+ FznsoIncomplete,
6060+ // An error occurred during the solver's execution.
6161+ //
6262+ // [`fznso_solver_read_error`] can be used to retrieve the error message.
6363+ FznsoError,
6464+} FznsoStatus;
6565+6666+// The handle to a the data of a solution instance.
6767+//
6868+// This type is opaque to the user. Only pointers of this type are ever used.
6969+//
7070+// In implementation of the FZnSO interface, a pointer is generally cast to
7171+// this type, i.e. `(FznsoSolutionData*) my_solution`. A similar cast can be
7272+// used to cast the pointer back to the original type, e.g. `(MySolution*)
7373+// fznso_solution`.
7474+typedef void FznsoAnnotation;
7575+7676+// Representation of a type to signal and check whether an argument takes the
7777+// correct type.
7878+typedef struct FznsoType {
7979+ // Whether the type is a list of values.
8080+ bool list_of;
8181+ // Whether the argument can be or contain decision variables (represented
8282+ // as decision indexes).
8383+ bool decision;
8484+ // Whether expected type is an set of values of the base type.
8585+ bool set_of;
8686+ // Whether the expected type is optional (and can take the value of
8787+ // [`FznsoValueKind::FznsoValueAbsent`]).
8888+ bool opt;
8989+ // The expected base type of the argument.
9090+ enum FznsoTypeBase base;
9191+} FznsoType;
9292+9393+// Representation of a type of constraint, discerned by its identifier and the
9494+// types of its arguments.
9595+typedef struct FznsoConstraintType {
9696+ // The identifier of the constraint type.
9797+ const char *ident;
9898+ // The number of expected arguments for the constraint type.
9999+ size_t arg_len;
100100+ // The types of the expected arguments for the constraint type.
101101+ const struct FznsoType *arg_types;
102102+} FznsoConstraintType;
103103+104104+// A list of [`FznsoConstraintType`]s.
105105+//
106106+// This type is for example used to return from [`fznso_constraint_list`].
107107+typedef struct FznsoConstraintList {
108108+ // The number of elements in the `constraints` array.
109109+ size_t len;
110110+ // An array of constraint types.
111111+ const struct FznsoConstraintType *constraints;
112112+} FznsoConstraintList;
113113+114114+// The handle of a model instance.
115115+//
116116+// This type is opaque to the user. Only pointers of this type are ever used.
117117+//
118118+// In implementation of the FZnSO interface, a pointer is generally cast to
119119+// this type, i.e. `(FznsoModelData*) my_model`. A similar cast can be used to
120120+// cast the pointer back to the original type, e.g. `(MyModel*) fznso_model`.
121121+typedef void FznsoModel;
122122+123123+// The type of a value used as an argument or solution assignment.
124124+//
125125+// This type is opaque to the user. Only pointers of this type are ever used.
126126+//
127127+// In implementation of the FZnSO interface, a pointer is generally cast to
128128+// this type, e.g. `(FznsoValue*) my_value`. A similar cast can be used to cast
129129+// the pointer back to the original type, e.g. `(MyValue*) fznso_value`.
130130+typedef void FznsoValue;
131131+132132+// Wrapper type for the indexes that represent decision variables in the model.
133133+typedef size_t FznsoDecisionIdx;
134134+135135+// Wrapper type for the indexes that represent constraints in the model.
136136+typedef size_t FznsoConstraintIdx;
137137+138138+// A struct containing the function pointers to interact with a
139139+// [`FznsoValue`]
140140+typedef struct FznsoValueMethods {
141141+ // Function callback that returns the kind of the value.
142142+ enum FznsoValueKind (*kind)(const FznsoValue*);
143143+ // Function callback that returns the length of the value.
144144+ //
145145+ // In case [`FznsoValueMethods::kind`] returns
146146+ // [`FznsoValueKind::FznsoValueList`], the length is the number of elements
147147+ // in the list, accessible using [`FznsoValueMethods::get_element`].
148148+ //
149149+ // In case [`FznsoValueMethods::kind`] returns
150150+ // [`FznsoValueKind::FznsoValueSetInt`] or
151151+ // [`FznsoValueKind::FznsoValueSetFloat`], the length is the number of
152152+ // ranges in the set, accessible using
153153+ // [`FznsoValueMethods::get_range_int`] or
154154+ // [`FznsoValueMethods::get_range_float`].
155155+ //
156156+ // # Panics
157157+ //
158158+ // This function callback may panic if [`FznsoValueMethods::kind`] does not
159159+ // return [`FznsoValueKind::FznsoValueList`],
160160+ // [`FznsoValueKind::FznsoValueSetInt`], or
161161+ // [`FznsoValueKind::FznsoValueSetFloat`].
162162+ size_t (*len)(const FznsoValue*);
163163+ // Function callback that returns the decision variable index contained in
164164+ // the value.
165165+ //
166166+ // # Panics
167167+ //
168168+ // This function callback may panic if [`FznsoValueMethods::kind`] does not
169169+ // return [`FznsoValueKind::FznsoValueDecision`].
170170+ FznsoDecisionIdx (*get_decision)(const FznsoValue*);
171171+ // Function callback that returns the constraint index contained in the
172172+ // value.
173173+ //
174174+ // # Panics
175175+ //
176176+ // This function callback may panic if [`FznsoValueMethods::kind`] does not
177177+ // return [`FznsoValueKind::FznsoValueConstraint`].
178178+ FznsoConstraintIdx (*get_constraint)(const FznsoValue*);
179179+ // Function callback that returns the integer value contained in the value.
180180+ //
181181+ // # Panics
182182+ //
183183+ // This function callback may panic if [`FznsoValueMethods::kind`] does not
184184+ // return [`FznsoValueKind::FznsoValueInt`].
185185+ int64_t (*get_int)(const FznsoValue*);
186186+ // Function callback that returns the floating point value contained in the
187187+ // value.
188188+ //
189189+ // # Panics
190190+ //
191191+ // This function callback may panic if [`FznsoValueMethods::kind`] does not
192192+ // return [`FznsoValueKind::FznsoValueFloat`].
193193+ double (*get_float)(const FznsoValue*);
194194+ // Function callback that returns the string pointer value contained in the
195195+ // value.
196196+ //
197197+ // # Panics
198198+ //
199199+ // This function callback may panic if [`FznsoValueMethods::kind`] does not
200200+ // return [`FznsoValueKind::FznsoValueString`].
201201+ const char *(*get_string)(const FznsoValue*);
202202+ // Function callback that returns the Boolean value contained in the value.
203203+ //
204204+ // # Panics
205205+ //
206206+ // This function callback may panic if [`FznsoValueMethods::kind`] does not
207207+ // return [`FznsoValueKind::FznsoValueBool`].
208208+ bool (*get_bool)(const FznsoValue*);
209209+ // Function callback that returns a range from a range list representing
210210+ // the integer set contained in the value.
211211+ //
212212+ // # Panics
213213+ //
214214+ // This function callback may panic if [`FznsoValueMethods::kind`] does not
215215+ // return [`FznsoValueKind::FznsoValueSetInt`].
216216+ int64_t ((*get_range_int)(const FznsoValue*, size_t index))[2];
217217+ // Function callback that returns a range from a range list representing
218218+ // the floating point set contained in the value.
219219+ //
220220+ // # Panics
221221+ //
222222+ // This function callback may panic if [`FznsoValueMethods::kind`] does not
223223+ // return [`FznsoValueKind::FznsoValueSetFloat`].
224224+ double ((*get_range_float)(const FznsoValue*, size_t index))[2];
225225+ // Function callback that returns an element from the list contained in the
226226+ // value.
227227+ //
228228+ // # Panics
229229+ //
230230+ // This function callback may panic if [`FznsoValueMethods::kind`] does not
231231+ // return [`FznsoValueKind::FznsoValueList`].
232232+ struct FznsoValueRef (*get_element)(const FznsoValue*, size_t index);
233233+} FznsoValueMethods;
234234+235235+// Handle for a value
236236+//
237237+// The caller can use the `get_value` function to retrieve the value of the
238238+// used decision variables.
239239+typedef struct FznsoValueRef {
240240+ // The data pointer to be the first argument of `get_value`.
241241+ const FznsoValue *data;
242242+ // Reference to the structure containing the function callbacks used to
243243+ // interact with the value.
244244+ const struct FznsoValueMethods *methods;
245245+} FznsoValueRef;
246246+247247+// A struct containing the function pointers to interact with the
248248+// [`FznsoModel`]
249249+typedef struct FznsoModelMethods {
250250+ // Returns the current number of model layers currently contained in the
251251+ // model.
252252+ //
253253+ // Layers provides a way for the modelling user to add and retract
254254+ size_t (*layer_len)(const FznsoModel *model);
255255+ // Returns the number of layers that have been unchanged since the last
256256+ // call to [`fznso_solver_run`].
257257+ //
258258+ // Unchanged layers must be consecutive starting from layer 0.
259259+ size_t (*layer_unchanged)(const FznsoModel *model);
260260+ // Returns the number of permanent layers in the model.
261261+ //
262262+ // Permanent layers are laid out must be consecutive starting from layer 0.
263263+ // Under no circumstances can they be retracted. As such, the solver can
264264+ // assume that the number of permanent layers only ever increases.
265265+ //
266266+ // Permanent layers can, however, still be found to be redundant, allowing
267267+ // the solver to remove the decision variables and constraints in these
268268+ // layers, if convenient. This is signaled using [`layer_redundant_len`]
269269+ // and [`layer_redundant_index`].
270270+ size_t (*layer_permanent)(const FznsoModel *model);
271271+ // Returns the number of permanent layers that have been marked as
272272+ // redundant.
273273+ //
274274+ // The solver can remove the decision variables and constraints in these
275275+ // layers, if convenient. Once a layer is marked as redundant, it can
276276+ // forever be considered redundant. As such, the solver can assume that
277277+ // the number of redundant layers only ever increases.
278278+ size_t (*layer_redundant_len)(const FznsoModel *model);
279279+ // Returns the index of the n-th permanent layer that has been marked as
280280+ // redundant.
281281+ //
282282+ // The `n` argument must be less than the value returned by
283283+ // [`layer_redundant_len`].
284284+ size_t (*layer_redundant_index)(const FznsoModel *model, size_t n);
285285+ // Retrieve the number of decisions currently contained in the model.
286286+ size_t (*decision_len)(const FznsoModel *model);
287287+ // Retrieve the decision index of the last decision variable in the layer.
288288+ //
289289+ // This can be equivalent to `decision_layer_end` of `layer-1` if the layer
290290+ // does not add any new decisions.
291291+ size_t (*decision_layer_end)(const FznsoModel *model, size_t layer);
292292+ // Retrieve the domain of the given decision.
293293+ //
294294+ // Note that the the value might have [`FznsoValueKind::FznsoValueAbsent`]
295295+ // if the decision variable does not have an explicit domain.
296296+ struct FznsoValueRef (*decision_domain)(const FznsoModel *model, FznsoDecisionIdx decision);
297297+ // Retrieve the name of a decision variable, if it exists.
298298+ //
299299+ // Note that names are only available for debugging purposes. Decisions are
300300+ // identified using their index in the model. If the decision variable does
301301+ // not have a name, this function returns a null pointer.
302302+ const char *(*decision_name)(const FznsoModel *model, FznsoDecisionIdx decision);
303303+ // Check whether the decision variable is defined by a constraint.
304304+ bool (*decision_defined)(const FznsoModel *model, FznsoDecisionIdx decision);
305305+ // Retrieve the number of annotations of a constraint.
306306+ size_t (*decision_annotation_len)(const FznsoModel *model, FznsoDecisionIdx decision);
307307+ // Retrieve the value of the constraint's annotation at the given index.
308308+ //
309309+ // The `index` argument must be less than the value returned by
310310+ // [`decision_annotation_len`] for the given decision variable.
311311+ const FznsoAnnotation *(*decision_annotation)(const FznsoModel *model,
312312+ FznsoDecisionIdx decision,
313313+ size_t index);
314314+ // Retrieve the number of constraints currently contained in the model.
315315+ size_t (*constraint_len)(const FznsoModel *model);
316316+ // Retrieve the constraint index of the first new constraint in the layer.
317317+ //
318318+ // This can be equivalent to `constraint_len` if the layer does not add any
319319+ // new constraints.
320320+ size_t (*constraint_layer_end)(const FznsoModel *model);
321321+ // Retrieve the identifier of a constraint.
322322+ //
323323+ // The returned pointer can be assumed to have the the same lifetime as the
324324+ // model reference and must be valid UTF8.
325325+ const char *(*constraint_ident)(const FznsoModel *model, FznsoConstraintIdx constraint);
326326+ // Retrieve the number of arguments of a constraint.
327327+ size_t (*constraint_argument_len)(const FznsoModel *model, FznsoConstraintIdx constraint);
328328+ // Retrieve the value of the constraint's argument at the given index.
329329+ //
330330+ // The `index` argument must be less than the value returned by
331331+ // `constraint_argument_len` for the given constraint.
332332+ struct FznsoValueRef (*constraint_argument)(const FznsoModel *model,
333333+ FznsoConstraintIdx constraint,
334334+ size_t index);
335335+ // Check whether the decision variable is functionally defined by a
336336+ // constraint.
337337+ //
338338+ // This function returns a [`FznsoValue`] that is either
339339+ // [`FznsoValueKind::FznsoValueDecision`] if it defined a decision variable
340340+ // or [`FznsoValueKind::FznsoValueAbsent`] otherwise.
341341+ struct FznsoValueRef (*constraint_defines)(const FznsoModel *model, FznsoConstraintIdx constraint);
342342+ // Retrieve the number of annotations on a constraint.
343343+ size_t (*constraint_annotation_len)(const FznsoModel *model, FznsoConstraintIdx constraint);
344344+ // Retrieve the annotation on a constraint at the given index.
345345+ //
346346+ // The `index` argument must be less than the value returned by
347347+ // `constraint_annotation_len` for the given constraint.
348348+ const FznsoAnnotation *(*constraint_annotation)(const FznsoModel *model,
349349+ FznsoConstraintIdx constraint,
350350+ size_t index);
351351+ // Request the identifier of the type of objective strategy to be used when
352352+ // solving the model.
353353+ //
354354+ // Note that the function can return a null pointer if the model does not
355355+ // have an objective strategy.
356356+ const char *(*objective_ident)(const FznsoModel *model);
357357+ // Retrieve the argument of the objective strategy.
358358+ struct FznsoValueRef (*objective_arg)(const FznsoModel *model);
359359+ // Retrieve the number of annotations on an objective
360360+ size_t (*objective_annotation_len)(const FznsoModel *model);
361361+ // Retrieve the annotation on the objective at the given index.
362362+ //
363363+ // The `index` argument must be less than the value returned by
364364+ // `objective_annotation_len`.
365365+ const FznsoAnnotation *(*objective_annotation)(const FznsoModel *model, size_t index);
366366+ // Retrieve the identifier of an annotation.
367367+ //
368368+ // The returned pointer can be assumed to have the the same lifetime as the
369369+ // annotation reference and must be valid UTF8.
370370+ const char *(*annotation_ident)(const FznsoAnnotation *ann);
371371+ // Retrieve the number of arguments of an annotation.
372372+ size_t (*annotation_argument_len)(const FznsoAnnotation *ann);
373373+ // Retrieve the value of the annotation's argument at the given index.
374374+ //
375375+ // The `index` argument must be less than the value returned by
376376+ // `annotation_argument_len` for the given annotation.
377377+ struct FznsoValueRef (*annotation_argument)(const FznsoAnnotation *ann, size_t index);
378378+} FznsoModelMethods;
379379+380380+// An interface to a model instance used to communicate with the solver.
381381+//
382382+// The solver can use the included function callbacks to interact with the
383383+// model.
384384+typedef struct FznsoModelRef {
385385+ // The handle to the data of the model instance.
386386+ const FznsoModel *data;
387387+ // Reference to the structure containing the function callbacks used to
388388+ // interact with the model.
389389+ const struct FznsoModelMethods *methods;
390390+} FznsoModelRef;
391391+392392+// Representation of a type of objective strategies, discerned by its
393393+// identifier and the type of its argument.
394394+typedef struct FznsoObjective {
395395+ // The identifier of the objective type.
396396+ const char *ident;
397397+ // The type of the expected argument for the constraint type.
398398+ struct FznsoType arg_type;
399399+} FznsoObjective;
400400+401401+// A list of [`FznsoObjective`]s.
402402+//
403403+// This type is, for example, used to return from [`fznso_objective_list`].
404404+typedef struct FznsoObjectiveList {
405405+ // The number of elements in the `options` array.
406406+ size_t len;
407407+ // An array of option definitions.
408408+ const struct FznsoObjective *options;
409409+} FznsoObjectiveList;
410410+411411+// The definition of an option that is available to be set for the solver.
412412+typedef struct FznsoOption {
413413+ // The identifier used to set the option or get the current value of the
414414+ // option.
415415+ const char *ident;
416416+ // The type of value that is expected for this option.
417417+ struct FznsoValueRef arg_ty;
418418+ // The default value for this option.
419419+ struct FznsoType arg_def;
420420+} FznsoOption;
421421+422422+// A list of [`FznsoOption`]s.
423423+//
424424+// This type is, for example, used to return from [`fznso_option_list`].
425425+typedef struct FznsoOptionList {
426426+ // The number of elements in the `options` array.
427427+ size_t len;
428428+ // An array of option definitions.
429429+ const struct FznsoOption *options;
430430+} FznsoOptionList;
431431+432432+// The handle to a the data of a solution instance.
433433+//
434434+// This type is opaque to the user. Only pointers of this type are ever used.
435435+//
436436+// In implementation of the FZnSO interface, a pointer is generally cast to
437437+// this type, i.e. `(FznsoSolutionData*) my_solution`. A similar cast can be
438438+// used to cast the pointer back to the original type, e.g. `(MySolution*)
439439+// fznso_solution`.
440440+typedef void FznsoSolution;
441441+442442+// A struct containing the function pointers to interact with a
443443+// [`FznsoSolution`]
444444+typedef struct FznsoSolutionMethods {
445445+ // Function callback to retrieve the value assigned to a decision variable
446446+ // in the solution.
447447+ struct FznsoValueRef (*get_value)(const FznsoSolution *data, size_t decision_index);
448448+ // Function callback to retrieve the statistical information made available
449449+ // by the solver about the search process so far.
450450+ struct FznsoValueRef (*get_statistic)(const FznsoSolution *data, const char *ident);
451451+} FznsoSolutionMethods;
452452+453453+// Handle for a solution emitted by the solver.
454454+typedef struct FznsoSolutionRef {
455455+ // The data pointer to be the first argument of `get_value`.
456456+ const FznsoSolution *data;
457457+ // Reference to the structure containing the function callbacks used to
458458+ // interact with the solution.
459459+ const struct FznsoSolutionMethods *methods;
460460+} FznsoSolutionRef;
461461+462462+// The handle to a solver instance.
463463+//
464464+// This type is opaque to the user. Only pointers of this type are ever used.
465465+//
466466+// In implementation of the FZnSO interface, a pointer is generally cast to
467467+// this type, i.e. `(FznsoSolver*) my_solver`. A similar cast can be used to
468468+// cast the pointer back to the original type, e.g. `(MySolverType*)
469469+// fznso_solver`.
470470+typedef void FznsoSolver;
471471+472472+// The definition of statistical information that is made available by the
473473+// solver.
474474+typedef struct FznsoStatistic {
475475+ // The identifier used to retrieve the statistical information from the
476476+ // solver or a solution.
477477+ const char *ident;
478478+ // The type of value that is expected for this option.
479479+ struct FznsoValueRef ty;
480480+ // Whether the statistical information is available as part of solutions.
481481+ bool solution;
482482+ // Whether the statistical information is generally available from the
483483+ // solver instance.
484484+ bool solver;
485485+} FznsoStatistic;
486486+487487+// A list of [`FznsoStatistic`]s.
488488+//
489489+// This type is, for example, used to return from [`fznso_statistic_list`].
490490+typedef struct FznsoStatisticList {
491491+ // The number of elements in the `stats` array.
492492+ size_t len;
493493+ // An array of statistical information definitions.
494494+ const struct FznsoStatistic *stats;
495495+} FznsoStatisticList;
496496+497497+// A list of [`FznsoType`]s.
498498+//
499499+// This type is for example used to return from [`fznso_decision_list`].
500500+typedef struct FznsoTypeList {
501501+ // The number of elements in the `constraints` array.
502502+ size_t len;
503503+ // An array of constraint types.
504504+ const struct FznsoType *types;
505505+} FznsoTypeList;
506506+507507+#endif /* fznso_types_h */
···11-#include "ipdos_types.h"
11+#include "fznso_types.h"
2233// Returns the list of available constraint that can be added to the solver.
44-IpdosConstraintList ipdos_constraint_list(void);
44+FznsoConstraintList fznso_constraint_list(void);
5566// Returns the list of types for which decision variable can be created by the
77// solver.
88-IpdosTypeList ipdos_decision_list(void);
88+FznsoTypeList fznso_decision_list(void);
991010// Returns the list of available objective that can be achieved by the solver.
1111-IpdosObjectiveList ipdos_objective_list(void);
1111+FznsoObjectiveList fznso_objective_list(void);
12121313// Returns the list of available options that can be set of the solver.
1414-IpdosOptionList ipdos_option_list(void);
1414+FznsoOptionList fznso_option_list(void);
15151616// Create a new solver instance
1717-IpdosSolver *ipdos_solver_create(void);
1717+FznsoSolver *fznso_solver_create(void);
18181919// Free a solver instance, releasing all resources associated with it.
2020//
2121// The pointer to the solver instance will be invalid after this function has
2222// been called.
2323-void ipdos_solver_free(IpdosSolver *solver);
2323+void fznso_solver_free(FznsoSolver *solver);
24242525// Get the current value of an option for the solver.
2626//
2727// Note that this is only valid to be called with options named by
2828-// `ipdos_option_list`.
2929-IpdosValueRef ipdos_solver_option_get(const IpdosSolver *solver, const char *ident);
2828+// `fznso_option_list`.
2929+FznsoValueRef fznso_solver_option_get(const FznsoSolver *solver, const char *ident);
30303131// Set the current value of an option for the solver.
3232//
3333// Note that this is only valid to be called with options named by
3434-// `ipdos_option_list`, and the value must be of the correct type.
3535-bool ipdos_solver_option_set(IpdosSolver *solver, const char *ident, IpdosValueRef value);
3434+// `fznso_option_list`, and the value must be of the correct type.
3535+bool fznso_solver_option_set(FznsoSolver *solver, const char *ident, FznsoValueRef value);
36363737// Read an error message from the solver.
3838//
3939// This function is expected to be called after solver interactions signal an
4040-// error has occurred. For example, if [`ipdos_solver_run`] returns
4141-// [`IpdosError`] or [`ipdos_solver_push`] returns `false`.
4242-void ipdos_solver_read_error(IpdosSolver *solver,
4040+// error has occurred. For example, if [`fznso_solver_run`] returns
4141+// [`FznsoError`] or [`fznso_solver_push`] returns `false`.
4242+void fznso_solver_read_error(FznsoSolver *solver,
4343 void *context,
4444 void (*read_error)(void *context, const char *error));
45454646// Run the solver with the given model
4747-IpdosStatus ipdos_solver_run(IpdosSolver *solver,
4848- IpdosModelRef model,
4747+FznsoStatus fznso_solver_run(FznsoSolver *solver,
4848+ FznsoModelRef model,
4949 void *context,
5050- void (*on_solution)(void *context, IpdosSolutionRef solution));
5050+ void (*on_solution)(void *context, FznsoSolutionRef solution));
51515252// Returns the list of available statistical information that can be requested
5353// from the solver and its solutions.
5454-IpdosStatisticList ipdos_statistic_list(void);
5454+FznsoStatisticList fznso_statistic_list(void);
-507
c/ipdos_types.h
···11-#ifndef ipdos_types_h
22-#define ipdos_types_h
33-44-#include <stdbool.h>
55-#include <stdint.h>
66-77-// The status returned by `ipdos_solver_run`, indicating whether the solver
88-// completed its search.
99-typedef enum IpdosStatus {
1010- // The solver explored the full search space and yielded all relevant
1111- // solutions.
1212- IpdosComplete,
1313- // The solver did not explore the full search space due to a timeout or
1414- // other termination condition. Additional (better) solutions might be
1515- // possible.
1616- IpdosIncomplete,
1717- // An error occurred during the solver's execution.
1818- //
1919- // [`ipdos_solver_read_error`] can be used to retrieve the error message.
2020- IpdosError,
2121-} IpdosStatus;
2222-2323-// Representation of the base type of a value.
2424-typedef enum IpdosTypeBase {
2525- // Boolean type
2626- IpdosTypeBaseBool,
2727- // Integer numeric type
2828- IpdosTypeBaseInt,
2929- // Floating point numeric type
3030- IpdosTypeBaseFloat,
3131- // Character string type
3232- IpdosTypeBaseString,
3333-} IpdosTypeBase;
3434-3535-// Enumerated type used to mark the kind of [`IpdosValue`]. This is used to
3636-// determine which "get" method in [`IpdosValueMethods`] is safe to call.
3737-typedef enum IpdosValueKind {
3838- // No value is available.
3939- IpdosValueAbsent,
4040- // The value is available using [`IpdosValueMethods::get_decision`].
4141- IpdosValueDecision,
4242- // The value is available using [`IpdosValueMethods::get_constraint`].
4343- IpdosValueConstraint,
4444- // The value is available using [`IpdosValueMethods::get_bool`].
4545- IpdosValueBool,
4646- // The value is available using [`IpdosValueMethods::get_int`].
4747- IpdosValueInt,
4848- // The value is available using [`IpdosValueMethods::get_float`].
4949- IpdosValueFloat,
5050- // The value is available using [`IpdosValueMethods::get_string`].
5151- IpdosValueString,
5252- // Sets of integers are represented using a range list. The number of
5353- // ranges is available using [`IpdosValueMethods::len`], and the ranges can
5454- // be accessed using [`IpdosValueMethods::get_range_int`].
5555- IpdosValueSetInt,
5656- // Sets of floats are represented using a range list. The number of
5757- // ranges is available using [`IpdosValueMethods::len`], and the ranges can
5858- // be accessed using [`IpdosValueMethods::get_range_float`].
5959- IpdosValueSetFloat,
6060- // The length of the list can be accessed using
6161- // [`IpdosValueMethods::len`], and elements in the list can be
6262- // accessed using [`IpdosValueMethods::get_element`]
6363- IpdosValueList,
6464-} IpdosValueKind;
6565-6666-// The handle to a the data of a solution instance.
6767-//
6868-// This type is opaque to the user. Only pointers of this type are ever used.
6969-//
7070-// In implementation of the IPDOS interface, a pointer is generally cast to
7171-// this type, i.e. `(IpdosSolutionData*) my_solution`. A similar cast can be
7272-// used to cast the pointer back to the original type, e.g. `(MySolution*)
7373-// ipdos_solution`.
7474-typedef void IpdosAnnotation;
7575-7676-// Representation of a type to signal and check whether an argument takes the
7777-// correct type.
7878-typedef struct IpdosType {
7979- // Whether the type is a list of values.
8080- bool list_of;
8181- // Whether the argument can be or contain decision variables (represented
8282- // as decision indexes).
8383- bool decision;
8484- // Whether expected type is an set of values of the base type.
8585- bool set_of;
8686- // Whether the expected type is optional (and can take the value of
8787- // [`IpdosValueKind::IpdosValueAbsent`]).
8888- bool opt;
8989- // The expected base type of the argument.
9090- enum IpdosTypeBase base;
9191-} IpdosType;
9292-9393-// Representation of a type of constraint, discerned by its identifier and the
9494-// types of its arguments.
9595-typedef struct IpdosConstraintType {
9696- // The identifier of the constraint type.
9797- const char *ident;
9898- // The number of expected arguments for the constraint type.
9999- size_t arg_len;
100100- // The types of the expected arguments for the constraint type.
101101- const struct IpdosType *arg_types;
102102-} IpdosConstraintType;
103103-104104-// A list of [`IpdosConstraintType`]s.
105105-//
106106-// This type is for example used to return from [`ipdos_constraint_list`].
107107-typedef struct IpdosConstraintList {
108108- // The number of elements in the `constraints` array.
109109- size_t len;
110110- // An array of constraint types.
111111- const struct IpdosConstraintType *constraints;
112112-} IpdosConstraintList;
113113-114114-// The handle of a model instance.
115115-//
116116-// This type is opaque to the user. Only pointers of this type are ever used.
117117-//
118118-// In implementation of the IPDOS interface, a pointer is generally cast to
119119-// this type, i.e. `(IpdosModelData*) my_model`. A similar cast can be used to
120120-// cast the pointer back to the original type, e.g. `(MyModel*) ipdos_model`.
121121-typedef void IpdosModel;
122122-123123-// The type of a value used as an argument or solution assignment.
124124-//
125125-// This type is opaque to the user. Only pointers of this type are ever used.
126126-//
127127-// In implementation of the IPDOS interface, a pointer is generally cast to
128128-// this type, e.g. `(IpdosValue*) my_value`. A similar cast can be used to cast
129129-// the pointer back to the original type, e.g. `(MyValue*) ipdos_value`.
130130-typedef void IpdosValue;
131131-132132-// Wrapper type for the indexes that represent decision variables in the model.
133133-typedef size_t IpdosDecisionIdx;
134134-135135-// Wrapper type for the indexes that represent constraints in the model.
136136-typedef size_t IpdosConstraintIdx;
137137-138138-// A struct containing the function pointers to interact with a
139139-// [`IpdosValue`]
140140-typedef struct IpdosValueMethods {
141141- // Function callback that returns the kind of the value.
142142- enum IpdosValueKind (*kind)(const IpdosValue*);
143143- // Function callback that returns the length of the value.
144144- //
145145- // In case [`IpdosValueMethods::kind`] returns
146146- // [`IpdosValueKind::IpdosValueList`], the length is the number of elements
147147- // in the list, accessible using [`IpdosValueMethods::get_element`].
148148- //
149149- // In case [`IpdosValueMethods::kind`] returns
150150- // [`IpdosValueKind::IpdosValueSetInt`] or
151151- // [`IpdosValueKind::IpdosValueSetFloat`], the length is the number of
152152- // ranges in the set, accessible using
153153- // [`IpdosValueMethods::get_range_int`] or
154154- // [`IpdosValueMethods::get_range_float`].
155155- //
156156- // # Panics
157157- //
158158- // This function callback may panic if [`IpdosValueMethods::kind`] does not
159159- // return [`IpdosValueKind::IpdosValueList`],
160160- // [`IpdosValueKind::IpdosValueSetInt`], or
161161- // [`IpdosValueKind::IpdosValueSetFloat`].
162162- size_t (*len)(const IpdosValue*);
163163- // Function callback that returns the decision variable index contained in
164164- // the value.
165165- //
166166- // # Panics
167167- //
168168- // This function callback may panic if [`IpdosValueMethods::kind`] does not
169169- // return [`IpdosValueKind::IpdosValueDecision`].
170170- IpdosDecisionIdx (*get_decision)(const IpdosValue*);
171171- // Function callback that returns the constraint index contained in the
172172- // value.
173173- //
174174- // # Panics
175175- //
176176- // This function callback may panic if [`IpdosValueMethods::kind`] does not
177177- // return [`IpdosValueKind::IpdosValueConstraint`].
178178- IpdosConstraintIdx (*get_constraint)(const IpdosValue*);
179179- // Function callback that returns the integer value contained in the value.
180180- //
181181- // # Panics
182182- //
183183- // This function callback may panic if [`IpdosValueMethods::kind`] does not
184184- // return [`IpdosValueKind::IpdosValueInt`].
185185- int64_t (*get_int)(const IpdosValue*);
186186- // Function callback that returns the floating point value contained in the
187187- // value.
188188- //
189189- // # Panics
190190- //
191191- // This function callback may panic if [`IpdosValueMethods::kind`] does not
192192- // return [`IpdosValueKind::IpdosValueFloat`].
193193- double (*get_float)(const IpdosValue*);
194194- // Function callback that returns the string pointer value contained in the
195195- // value.
196196- //
197197- // # Panics
198198- //
199199- // This function callback may panic if [`IpdosValueMethods::kind`] does not
200200- // return [`IpdosValueKind::IpdosValueString`].
201201- const char *(*get_string)(const IpdosValue*);
202202- // Function callback that returns the Boolean value contained in the value.
203203- //
204204- // # Panics
205205- //
206206- // This function callback may panic if [`IpdosValueMethods::kind`] does not
207207- // return [`IpdosValueKind::IpdosValueBool`].
208208- bool (*get_bool)(const IpdosValue*);
209209- // Function callback that returns a range from a range list representing
210210- // the integer set contained in the value.
211211- //
212212- // # Panics
213213- //
214214- // This function callback may panic if [`IpdosValueMethods::kind`] does not
215215- // return [`IpdosValueKind::IpdosValueSetInt`].
216216- int64_t ((*get_range_int)(const IpdosValue*, size_t index))[2];
217217- // Function callback that returns a range from a range list representing
218218- // the floating point set contained in the value.
219219- //
220220- // # Panics
221221- //
222222- // This function callback may panic if [`IpdosValueMethods::kind`] does not
223223- // return [`IpdosValueKind::IpdosValueSetFloat`].
224224- double ((*get_range_float)(const IpdosValue*, size_t index))[2];
225225- // Function callback that returns an element from the list contained in the
226226- // value.
227227- //
228228- // # Panics
229229- //
230230- // This function callback may panic if [`IpdosValueMethods::kind`] does not
231231- // return [`IpdosValueKind::IpdosValueList`].
232232- struct IpdosValueRef (*get_element)(const IpdosValue*, size_t index);
233233-} IpdosValueMethods;
234234-235235-// Handle for a value
236236-//
237237-// The caller can use the `get_value` function to retrieve the value of the
238238-// used decision variables.
239239-typedef struct IpdosValueRef {
240240- // The data pointer to be the first argument of `get_value`.
241241- const IpdosValue *data;
242242- // Reference to the structure containing the function callbacks used to
243243- // interact with the value.
244244- const struct IpdosValueMethods *methods;
245245-} IpdosValueRef;
246246-247247-// A struct containing the function pointers to interact with the
248248-// [`IpdosModel`]
249249-typedef struct IpdosModelMethods {
250250- // Returns the current number of model layers currently contained in the
251251- // model.
252252- //
253253- // Layers provides a way for the modelling user to add and retract
254254- size_t (*layer_len)(const IpdosModel *model);
255255- // Returns the number of layers that have been unchanged since the last
256256- // call to [`ipdos_solver_run`].
257257- //
258258- // Unchanged layers must be consecutive starting from layer 0.
259259- size_t (*layer_unchanged)(const IpdosModel *model);
260260- // Returns the number of permanent layers in the model.
261261- //
262262- // Permanent layers are laid out must be consecutive starting from layer 0.
263263- // Under no circumstances can they be retracted. As such, the solver can
264264- // assume that the number of permanent layers only ever increases.
265265- //
266266- // Permanent layers can, however, still be found to be redundant, allowing
267267- // the solver to remove the decision variables and constraints in these
268268- // layers, if convenient. This is signaled using [`layer_redundant_len`]
269269- // and [`layer_redundant_index`].
270270- size_t (*layer_permanent)(const IpdosModel *model);
271271- // Returns the number of permanent layers that have been marked as
272272- // redundant.
273273- //
274274- // The solver can remove the decision variables and constraints in these
275275- // layers, if convenient. Once a layer is marked as redundant, it can
276276- // forever be considered redundant. As such, the solver can assume that
277277- // the number of redundant layers only ever increases.
278278- size_t (*layer_redundant_len)(const IpdosModel *model);
279279- // Returns the index of the n-th permanent layer that has been marked as
280280- // redundant.
281281- //
282282- // The `n` argument must be less than the value returned by
283283- // [`layer_redundant_len`].
284284- size_t (*layer_redundant_index)(const IpdosModel *model, size_t n);
285285- // Retrieve the number of decisions currently contained in the model.
286286- size_t (*decision_len)(const IpdosModel *model);
287287- // Retrieve the decision index of the last decision variable in the layer.
288288- //
289289- // This can be equivalent to `decision_layer_end` of `layer-1` if the layer
290290- // does not add any new decisions.
291291- size_t (*decision_layer_end)(const IpdosModel *model, size_t layer);
292292- // Retrieve the domain of the given decision.
293293- //
294294- // Note that the the value might have [`IpdosValueKind::IpdosValueAbsent`]
295295- // if the decision variable does not have an explicit domain.
296296- struct IpdosValueRef (*decision_domain)(const IpdosModel *model, IpdosDecisionIdx decision);
297297- // Retrieve the name of a decision variable, if it exists.
298298- //
299299- // Note that names are only available for debugging purposes. Decisions are
300300- // identified using their index in the model. If the decision variable does
301301- // not have a name, this function returns a null pointer.
302302- const char *(*decision_name)(const IpdosModel *model, IpdosDecisionIdx decision);
303303- // Check whether the decision variable is defined by a constraint.
304304- bool (*decision_defined)(const IpdosModel *model, IpdosDecisionIdx decision);
305305- // Retrieve the number of annotations of a constraint.
306306- size_t (*decision_annotation_len)(const IpdosModel *model, IpdosDecisionIdx decision);
307307- // Retrieve the value of the constraint's annotation at the given index.
308308- //
309309- // The `index` argument must be less than the value returned by
310310- // [`decision_annotation_len`] for the given decision variable.
311311- const IpdosAnnotation *(*decision_annotation)(const IpdosModel *model,
312312- IpdosDecisionIdx decision,
313313- size_t index);
314314- // Retrieve the number of constraints currently contained in the model.
315315- size_t (*constraint_len)(const IpdosModel *model);
316316- // Retrieve the constraint index of the first new constraint in the layer.
317317- //
318318- // This can be equivalent to `constraint_len` if the layer does not add any
319319- // new constraints.
320320- size_t (*constraint_layer_end)(const IpdosModel *model);
321321- // Retrieve the identifier of a constraint.
322322- //
323323- // The returned pointer can be assumed to have the the same lifetime as the
324324- // model reference and must be valid UTF8.
325325- const char *(*constraint_ident)(const IpdosModel *model, IpdosConstraintIdx constraint);
326326- // Retrieve the number of arguments of a constraint.
327327- size_t (*constraint_argument_len)(const IpdosModel *model, IpdosConstraintIdx constraint);
328328- // Retrieve the value of the constraint's argument at the given index.
329329- //
330330- // The `index` argument must be less than the value returned by
331331- // `constraint_argument_len` for the given constraint.
332332- struct IpdosValueRef (*constraint_argument)(const IpdosModel *model,
333333- IpdosConstraintIdx constraint,
334334- size_t index);
335335- // Check whether the decision variable is functionally defined by a
336336- // constraint.
337337- //
338338- // This function returns a [`IpdosValue`] that is either
339339- // [`IpdosValueKind::IpdosValueDecision`] if it defined a decision variable
340340- // or [`IpdosValueKind::IpdosValueAbsent`] otherwise.
341341- struct IpdosValueRef (*constraint_defines)(const IpdosModel *model, IpdosConstraintIdx constraint);
342342- // Retrieve the number of annotations on a constraint.
343343- size_t (*constraint_annotation_len)(const IpdosModel *model, IpdosConstraintIdx constraint);
344344- // Retrieve the annotation on a constraint at the given index.
345345- //
346346- // The `index` argument must be less than the value returned by
347347- // `constraint_annotation_len` for the given constraint.
348348- const IpdosAnnotation *(*constraint_annotation)(const IpdosModel *model,
349349- IpdosConstraintIdx constraint,
350350- size_t index);
351351- // Request the identifier of the type of objective strategy to be used when
352352- // solving the model.
353353- //
354354- // Note that the function can return a null pointer if the model does not
355355- // have an objective strategy.
356356- const char *(*objective_ident)(const IpdosModel *model);
357357- // Retrieve the argument of the objective strategy.
358358- struct IpdosValueRef (*objective_arg)(const IpdosModel *model);
359359- // Retrieve the number of annotations on an objective
360360- size_t (*objective_annotation_len)(const IpdosModel *model);
361361- // Retrieve the annotation on the objective at the given index.
362362- //
363363- // The `index` argument must be less than the value returned by
364364- // `objective_annotation_len`.
365365- const IpdosAnnotation *(*objective_annotation)(const IpdosModel *model, size_t index);
366366- // Retrieve the identifier of an annotation.
367367- //
368368- // The returned pointer can be assumed to have the the same lifetime as the
369369- // annotation reference and must be valid UTF8.
370370- const char *(*annotation_ident)(const IpdosAnnotation *ann);
371371- // Retrieve the number of arguments of an annotation.
372372- size_t (*annotation_argument_len)(const IpdosAnnotation *ann);
373373- // Retrieve the value of the annotation's argument at the given index.
374374- //
375375- // The `index` argument must be less than the value returned by
376376- // `annotation_argument_len` for the given annotation.
377377- struct IpdosValueRef (*annotation_argument)(const IpdosAnnotation *ann, size_t index);
378378-} IpdosModelMethods;
379379-380380-// An interface to a model instance used to communicate with the solver.
381381-//
382382-// The solver can use the included function callbacks to interact with the
383383-// model.
384384-typedef struct IpdosModelRef {
385385- // The handle to the data of the model instance.
386386- const IpdosModel *data;
387387- // Reference to the structure containing the function callbacks used to
388388- // interact with the model.
389389- const struct IpdosModelMethods *methods;
390390-} IpdosModelRef;
391391-392392-// Representation of a type of objective strategies, discerned by its
393393-// identifier and the type of its argument.
394394-typedef struct IpdosObjective {
395395- // The identifier of the objective type.
396396- const char *ident;
397397- // The type of the expected argument for the constraint type.
398398- struct IpdosType arg_type;
399399-} IpdosObjective;
400400-401401-// A list of [`IpdosObjective`]s.
402402-//
403403-// This type is, for example, used to return from [`ipdos_objective_list`].
404404-typedef struct IpdosObjectiveList {
405405- // The number of elements in the `options` array.
406406- size_t len;
407407- // An array of option definitions.
408408- const struct IpdosObjective *options;
409409-} IpdosObjectiveList;
410410-411411-// The definition of an option that is available to be set for the solver.
412412-typedef struct IpdosOption {
413413- // The identifier used to set the option or get the current value of the
414414- // option.
415415- const char *ident;
416416- // The type of value that is expected for this option.
417417- struct IpdosValueRef arg_ty;
418418- // The default value for this option.
419419- struct IpdosType arg_def;
420420-} IpdosOption;
421421-422422-// A list of [`IpdosOption`]s.
423423-//
424424-// This type is, for example, used to return from [`ipdos_option_list`].
425425-typedef struct IpdosOptionList {
426426- // The number of elements in the `options` array.
427427- size_t len;
428428- // An array of option definitions.
429429- const struct IpdosOption *options;
430430-} IpdosOptionList;
431431-432432-// The handle to a the data of a solution instance.
433433-//
434434-// This type is opaque to the user. Only pointers of this type are ever used.
435435-//
436436-// In implementation of the IPDOS interface, a pointer is generally cast to
437437-// this type, i.e. `(IpdosSolutionData*) my_solution`. A similar cast can be
438438-// used to cast the pointer back to the original type, e.g. `(MySolution*)
439439-// ipdos_solution`.
440440-typedef void IpdosSolution;
441441-442442-// A struct containing the function pointers to interact with a
443443-// [`IpdosSolution`]
444444-typedef struct IpdosSolutionMethods {
445445- // Function callback to retrieve the value assigned to a decision variable
446446- // in the solution.
447447- struct IpdosValueRef (*get_value)(const IpdosSolution *data, size_t decision_index);
448448- // Function callback to retrieve the statistical information made available
449449- // by the solver about the search process so far.
450450- struct IpdosValueRef (*get_statistic)(const IpdosSolution *data, const char *ident);
451451-} IpdosSolutionMethods;
452452-453453-// Handle for a solution emitted by the solver.
454454-typedef struct IpdosSolutionRef {
455455- // The data pointer to be the first argument of `get_value`.
456456- const IpdosSolution *data;
457457- // Reference to the structure containing the function callbacks used to
458458- // interact with the solution.
459459- const struct IpdosSolutionMethods *methods;
460460-} IpdosSolutionRef;
461461-462462-// The handle to a solver instance.
463463-//
464464-// This type is opaque to the user. Only pointers of this type are ever used.
465465-//
466466-// In implementation of the IPDOS interface, a pointer is generally cast to
467467-// this type, i.e. `(IpdosSolver*) my_solver`. A similar cast can be used to
468468-// cast the pointer back to the original type, e.g. `(MySolverType*)
469469-// ipdos_solver`.
470470-typedef void IpdosSolver;
471471-472472-// The definition of statistical information that is made available by the
473473-// solver.
474474-typedef struct IpdosStatistic {
475475- // The identifier used to retrieve the statistical information from the
476476- // solver or a solution.
477477- const char *ident;
478478- // The type of value that is expected for this option.
479479- struct IpdosValueRef ty;
480480- // Whether the statistical information is available as part of solutions.
481481- bool solution;
482482- // Whether the statistical information is generally available from the
483483- // solver instance.
484484- bool solver;
485485-} IpdosStatistic;
486486-487487-// A list of [`IpdosStatistic`]s.
488488-//
489489-// This type is, for example, used to return from [`ipdos_statistic_list`].
490490-typedef struct IpdosStatisticList {
491491- // The number of elements in the `stats` array.
492492- size_t len;
493493- // An array of statistical information definitions.
494494- const struct IpdosStatistic *stats;
495495-} IpdosStatisticList;
496496-497497-// A list of [`IpdosType`]s.
498498-//
499499-// This type is for example used to return from [`ipdos_decision_list`].
500500-typedef struct IpdosTypeList {
501501- // The number of elements in the `constraints` array.
502502- size_t len;
503503- // An array of constraint types.
504504- const struct IpdosType *types;
505505-} IpdosTypeList;
506506-507507-#endif /* ipdos_types_h */
···11-//! IPDOS Protocol Solver Template
11+//! FZnSO Protocol Solver Template
22//!
33-//! This crate defines the solver functionality to be implemented IPDOS
33+//! This crate defines the solver functionality to be implemented FZnSO
44//! protocol, which allows the incremental usage of solvers that can solve
55//! decision and optimization problems. The goal of the interface is to easily
66//! use different solvers in a unified way, and to allow the dynamic loading of
···8899use core::ffi;
10101111-use ipdos_types::{
1212- IpdosConstraintList, IpdosModelRef, IpdosObjectiveList, IpdosOptionList, IpdosSolutionRef,
1313- IpdosSolver, IpdosStatisticList, IpdosStatus, IpdosTypeList, IpdosValueRef,
1111+use fznso_types::{
1212+ FznsoConstraintList, FznsoModelRef, FznsoObjectiveList, FznsoOptionList, FznsoSolutionRef,
1313+ FznsoSolver, FznsoStatisticList, FznsoStatus, FznsoTypeList, FznsoValueRef,
1414};
15151616#[unsafe(no_mangle)]
1717/// Returns the list of available constraint that can be added to the solver.
1818-pub extern "C" fn ipdos_constraint_list() -> IpdosConstraintList<'static> {
1818+pub extern "C" fn fznso_constraint_list() -> FznsoConstraintList<'static> {
1919 unimplemented!()
2020}
21212222#[unsafe(no_mangle)]
2323/// Returns the list of types for which decision variable can be created by the
2424/// solver.
2525-pub extern "C" fn ipdos_decision_list() -> IpdosTypeList<'static> {
2525+pub extern "C" fn fznso_decision_list() -> FznsoTypeList<'static> {
2626 unimplemented!()
2727}
28282929#[unsafe(no_mangle)]
3030/// Returns the list of available objective that can be achieved by the solver.
3131-pub extern "C" fn ipdos_objective_list() -> IpdosObjectiveList<'static> {
3131+pub extern "C" fn fznso_objective_list() -> FznsoObjectiveList<'static> {
3232 unimplemented!()
3333}
34343535#[unsafe(no_mangle)]
3636/// Returns the list of available options that can be set of the solver.
3737-pub extern "C" fn ipdos_option_list() -> IpdosOptionList<'static> {
3737+pub extern "C" fn fznso_option_list() -> FznsoOptionList<'static> {
3838 unimplemented!()
3939}
40404141#[unsafe(no_mangle)]
4242/// Create a new solver instance
4343-pub extern "C" fn ipdos_solver_create() -> *mut IpdosSolver {
4343+pub extern "C" fn fznso_solver_create() -> *mut FznsoSolver {
4444 unimplemented!()
4545}
4646···4949/// The pointer to the solver instance will be invalid after this function has
5050/// been called.
5151#[unsafe(no_mangle)]
5252-pub extern "C" fn ipdos_solver_free(solver: *mut IpdosSolver) {
5252+pub extern "C" fn fznso_solver_free(solver: *mut FznsoSolver) {
5353 let _ = solver;
5454 unimplemented!()
5555}
···5858/// Get the current value of an option for the solver.
5959///
6060/// Note that this is only valid to be called with options named by
6161-/// `ipdos_option_list`.
6262-pub extern "C" fn ipdos_solver_option_get(
6363- solver: &IpdosSolver,
6161+/// `fznso_option_list`.
6262+pub extern "C" fn fznso_solver_option_get(
6363+ solver: &FznsoSolver,
6464 ident: *const ffi::c_char,
6565-) -> IpdosValueRef<'_> {
6565+) -> FznsoValueRef<'_> {
6666 let _ = solver;
6767 let _ = ident;
6868 unimplemented!()
···7272/// Set the current value of an option for the solver.
7373///
7474/// Note that this is only valid to be called with options named by
7575-/// `ipdos_option_list`, and the value must be of the correct type.
7676-pub extern "C" fn ipdos_solver_option_set(
7777- solver: &mut IpdosSolver,
7575+/// `fznso_option_list`, and the value must be of the correct type.
7676+pub extern "C" fn fznso_solver_option_set(
7777+ solver: &mut FznsoSolver,
7878 ident: *const ffi::c_char,
7979- value: IpdosValueRef<'_>,
7979+ value: FznsoValueRef<'_>,
8080) -> bool {
8181 let _ = solver;
8282 let _ = ident;
···8888/// Read an error message from the solver.
8989///
9090/// This function is expected to be called after solver interactions signal an
9191-/// error has occurred. For example, if [`ipdos_solver_run`] returns
9292-/// [`IpdosError`] or [`ipdos_solver_push`] returns `false`.
9393-pub extern "C" fn ipdos_solver_read_error(
9494- solver: &mut IpdosSolver,
9191+/// error has occurred. For example, if [`fznso_solver_run`] returns
9292+/// [`FznsoError`] or [`fznso_solver_push`] returns `false`.
9393+pub extern "C" fn fznso_solver_read_error(
9494+ solver: &mut FznsoSolver,
9595 context: &mut ffi::c_void,
9696 read_error: extern "C" fn(context: &mut ffi::c_void, error: *const ffi::c_char),
9797) {
···103103104104#[unsafe(no_mangle)]
105105/// Run the solver with the given model
106106-pub extern "C" fn ipdos_solver_run(
107107- solver: &mut IpdosSolver,
108108- model: IpdosModelRef,
106106+pub extern "C" fn fznso_solver_run(
107107+ solver: &mut FznsoSolver,
108108+ model: FznsoModelRef,
109109 context: &mut ffi::c_void,
110110- on_solution: extern "C" fn(context: &mut ffi::c_void, solution: IpdosSolutionRef),
111111-) -> IpdosStatus {
110110+ on_solution: extern "C" fn(context: &mut ffi::c_void, solution: FznsoSolutionRef),
111111+) -> FznsoStatus {
112112 let _ = solver;
113113 let _ = model;
114114 let _ = context;
···119119#[unsafe(no_mangle)]
120120/// Returns the list of available statistical information that can be requested
121121/// from the solver and its solutions.
122122-pub extern "C" fn ipdos_statistic_list() -> IpdosStatisticList<'static> {
122122+pub extern "C" fn fznso_statistic_list() -> FznsoStatisticList<'static> {
123123 unimplemented!()
124124}
···11-//! IPDOS Protocol Types
11+//! FZnSO Protocol Types
22//!
33-//! This crate defines the types of the IPDOS protocol, which allows the
33+//! This crate defines the types of the FZnSO protocol, which allows the
44//! incremental usage of solvers that can solve decision and optimization
55//! problems. The goal of the interface is to easily use different solvers in a
66//! unified way, and to allow the dynamic loading of solver libraries (as DLLs).
···1515///
1616/// This type is opaque to the user. Only pointers of this type are ever used.
1717///
1818-/// In implementation of the IPDOS interface, a pointer is generally cast to
1919-/// this type, i.e. `(IpdosSolutionData*) my_solution`. A similar cast can be
1818+/// In implementation of the FZnSO interface, a pointer is generally cast to
1919+/// this type, i.e. `(FznsoSolutionData*) my_solution`. A similar cast can be
2020/// used to cast the pointer back to the original type, e.g. `(MySolution*)
2121-/// ipdos_solution`.
2222-pub struct IpdosAnnotation(ffi::c_void);
2121+/// fznso_solution`.
2222+pub struct FznsoAnnotation(ffi::c_void);
23232424#[repr(transparent)]
2525#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
2626/// Wrapper type for the indexes that represent constraints in the model.
2727-pub struct IpdosConstraintIdx(pub usize);
2727+pub struct FznsoConstraintIdx(pub usize);
28282929#[repr(C)]
3030#[derive(Clone, Debug)]
3131-/// A list of [`IpdosConstraintType`]s.
3131+/// A list of [`FznsoConstraintType`]s.
3232///
3333-/// This type is for example used to return from [`ipdos_constraint_list`].
3434-pub struct IpdosConstraintList<'a> {
3333+/// This type is for example used to return from [`fznso_constraint_list`].
3434+pub struct FznsoConstraintList<'a> {
3535 /// The number of elements in the `constraints` array.
3636 pub len: usize,
3737 /// An array of constraint types.
3838- pub constraints: *const IpdosConstraintType<'a>,
3838+ pub constraints: *const FznsoConstraintType<'a>,
3939 /// The lifetime for which the `constraints` attribute is allocated.
4040 pub lifetime: PhantomData<&'a ()>,
4141}
···4444#[derive(Clone, Debug)]
4545/// Representation of a type of constraint, discerned by its identifier and the
4646/// types of its arguments.
4747-pub struct IpdosConstraintType<'a> {
4747+pub struct FznsoConstraintType<'a> {
4848 /// The identifier of the constraint type.
4949 pub ident: *const ffi::c_char,
5050 /// The number of expected arguments for the constraint type.
5151 pub arg_len: usize,
5252 /// The types of the expected arguments for the constraint type.
5353- pub arg_types: *const IpdosType,
5353+ pub arg_types: *const FznsoType,
5454 /// The lifetime for which the `ident` and `arg_types` attributes are
5555 /// allocated.
5656 pub lifetime: PhantomData<&'a ()>,
···5959#[repr(transparent)]
6060#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
6161/// Wrapper type for the indexes that represent decision variables in the model.
6262-pub struct IpdosDecisionIdx(pub usize);
6262+pub struct FznsoDecisionIdx(pub usize);
63636464#[repr(transparent)]
6565#[derive(Debug)]
···6767///
6868/// This type is opaque to the user. Only pointers of this type are ever used.
6969///
7070-/// In implementation of the IPDOS interface, a pointer is generally cast to
7171-/// this type, i.e. `(IpdosModelData*) my_model`. A similar cast can be used to
7272-/// cast the pointer back to the original type, e.g. `(MyModel*) ipdos_model`.
7373-pub struct IpdosModel(ffi::c_void);
7070+/// In implementation of the FZnSO interface, a pointer is generally cast to
7171+/// this type, i.e. `(FznsoModelData*) my_model`. A similar cast can be used to
7272+/// cast the pointer back to the original type, e.g. `(MyModel*) fznso_model`.
7373+pub struct FznsoModel(ffi::c_void);
74747575#[repr(C)]
7676#[derive(Debug)]
7777/// A struct containing the function pointers to interact with the
7878-/// [`IpdosModel`]
7979-pub struct IpdosModelMethods {
7878+/// [`FznsoModel`]
7979+pub struct FznsoModelMethods {
8080 /// Returns the current number of model layers currently contained in the
8181 /// model.
8282 ///
8383 /// Layers provides a way for the modelling user to add and retract
8484- layer_len: extern "C" fn(model: &IpdosModel) -> usize,
8484+ layer_len: extern "C" fn(model: &FznsoModel) -> usize,
8585 /// Returns the number of layers that have been unchanged since the last
8686- /// call to [`ipdos_solver_run`].
8686+ /// call to [`fznso_solver_run`].
8787 ///
8888 /// Unchanged layers must be consecutive starting from layer 0.
8989- layer_unchanged: extern "C" fn(model: &IpdosModel) -> usize,
8989+ layer_unchanged: extern "C" fn(model: &FznsoModel) -> usize,
9090 /// Returns the number of permanent layers in the model.
9191 ///
9292 /// Permanent layers are laid out must be consecutive starting from layer 0.
···9797 /// the solver to remove the decision variables and constraints in these
9898 /// layers, if convenient. This is signaled using [`layer_redundant_len`]
9999 /// and [`layer_redundant_index`].
100100- layer_permanent: extern "C" fn(model: &IpdosModel) -> usize,
100100+ layer_permanent: extern "C" fn(model: &FznsoModel) -> usize,
101101 /// Returns the number of permanent layers that have been marked as
102102 /// redundant.
103103 ///
···105105 /// layers, if convenient. Once a layer is marked as redundant, it can
106106 /// forever be considered redundant. As such, the solver can assume that
107107 /// the number of redundant layers only ever increases.
108108- layer_redundant_len: extern "C" fn(model: &IpdosModel) -> usize,
108108+ layer_redundant_len: extern "C" fn(model: &FznsoModel) -> usize,
109109 /// Returns the index of the n-th permanent layer that has been marked as
110110 /// redundant.
111111 ///
112112 /// The `n` argument must be less than the value returned by
113113 /// [`layer_redundant_len`].
114114- layer_redundant_index: extern "C" fn(model: &IpdosModel, n: usize) -> usize,
114114+ layer_redundant_index: extern "C" fn(model: &FznsoModel, n: usize) -> usize,
115115116116 /// Retrieve the number of decisions currently contained in the model.
117117- decision_len: extern "C" fn(model: &IpdosModel) -> usize,
117117+ decision_len: extern "C" fn(model: &FznsoModel) -> usize,
118118 /// Retrieve the decision index of the last decision variable in the layer.
119119 ///
120120 /// This can be equivalent to `decision_layer_end` of `layer-1` if the layer
121121 /// does not add any new decisions.
122122- decision_layer_end: extern "C" fn(model: &IpdosModel, layer: usize) -> usize,
122122+ decision_layer_end: extern "C" fn(model: &FznsoModel, layer: usize) -> usize,
123123 /// Retrieve the domain of the given decision.
124124 ///
125125- /// Note that the the value might have [`IpdosValueKind::IpdosValueAbsent`]
125125+ /// Note that the the value might have [`FznsoValueKind::FznsoValueAbsent`]
126126 /// if the decision variable does not have an explicit domain.
127127 decision_domain:
128128- extern "C" fn(model: &IpdosModel, decision: IpdosDecisionIdx) -> IpdosValueRef<'_>,
128128+ extern "C" fn(model: &FznsoModel, decision: FznsoDecisionIdx) -> FznsoValueRef<'_>,
129129 /// Retrieve the name of a decision variable, if it exists.
130130 ///
131131 /// Note that names are only available for debugging purposes. Decisions are
132132 /// identified using their index in the model. If the decision variable does
133133 /// not have a name, this function returns a null pointer.
134134 decision_name:
135135- extern "C" fn(model: &IpdosModel, decision: IpdosDecisionIdx) -> *const ffi::c_char,
135135+ extern "C" fn(model: &FznsoModel, decision: FznsoDecisionIdx) -> *const ffi::c_char,
136136 /// Check whether the decision variable is defined by a constraint.
137137- decision_defined: extern "C" fn(model: &IpdosModel, decision: IpdosDecisionIdx) -> bool,
137137+ decision_defined: extern "C" fn(model: &FznsoModel, decision: FznsoDecisionIdx) -> bool,
138138 /// Retrieve the number of annotations of a constraint.
139139- decision_annotation_len: extern "C" fn(model: &IpdosModel, decision: IpdosDecisionIdx) -> usize,
139139+ decision_annotation_len: extern "C" fn(model: &FznsoModel, decision: FznsoDecisionIdx) -> usize,
140140 /// Retrieve the value of the constraint's annotation at the given index.
141141 ///
142142 /// The `index` argument must be less than the value returned by
143143 /// [`decision_annotation_len`] for the given decision variable.
144144 decision_annotation: extern "C" fn(
145145- model: &IpdosModel,
146146- decision: IpdosDecisionIdx,
145145+ model: &FznsoModel,
146146+ decision: FznsoDecisionIdx,
147147 index: usize,
148148- ) -> &IpdosAnnotation,
148148+ ) -> &FznsoAnnotation,
149149150150 /// Retrieve the number of constraints currently contained in the model.
151151- constraint_len: extern "C" fn(model: &IpdosModel) -> usize,
151151+ constraint_len: extern "C" fn(model: &FznsoModel) -> usize,
152152 /// Retrieve the constraint index of the first new constraint in the layer.
153153 ///
154154 /// This can be equivalent to `constraint_len` if the layer does not add any
155155 /// new constraints.
156156- constraint_layer_end: extern "C" fn(model: &IpdosModel) -> usize,
156156+ constraint_layer_end: extern "C" fn(model: &FznsoModel) -> usize,
157157 /// Retrieve the identifier of a constraint.
158158 ///
159159 /// The returned pointer can be assumed to have the the same lifetime as the
160160 /// model reference and must be valid UTF8.
161161 constraint_ident:
162162- extern "C" fn(model: &IpdosModel, constraint: IpdosConstraintIdx) -> *const ffi::c_char,
162162+ extern "C" fn(model: &FznsoModel, constraint: FznsoConstraintIdx) -> *const ffi::c_char,
163163 /// Retrieve the number of arguments of a constraint.
164164 constraint_argument_len:
165165- extern "C" fn(model: &IpdosModel, constraint: IpdosConstraintIdx) -> usize,
165165+ extern "C" fn(model: &FznsoModel, constraint: FznsoConstraintIdx) -> usize,
166166 /// Retrieve the value of the constraint's argument at the given index.
167167 ///
168168 /// The `index` argument must be less than the value returned by
169169 /// `constraint_argument_len` for the given constraint.
170170 constraint_argument: extern "C" fn(
171171- model: &IpdosModel,
172172- constraint: IpdosConstraintIdx,
171171+ model: &FznsoModel,
172172+ constraint: FznsoConstraintIdx,
173173 index: usize,
174174- ) -> IpdosValueRef<'_>,
174174+ ) -> FznsoValueRef<'_>,
175175 /// Check whether the decision variable is functionally defined by a
176176 /// constraint.
177177 ///
178178- /// This function returns a [`IpdosValue`] that is either
179179- /// [`IpdosValueKind::IpdosValueDecision`] if it defined a decision variable
180180- /// or [`IpdosValueKind::IpdosValueAbsent`] otherwise.
178178+ /// This function returns a [`FznsoValue`] that is either
179179+ /// [`FznsoValueKind::FznsoValueDecision`] if it defined a decision variable
180180+ /// or [`FznsoValueKind::FznsoValueAbsent`] otherwise.
181181 constraint_defines:
182182- extern "C" fn(model: &IpdosModel, constraint: IpdosConstraintIdx) -> IpdosValueRef<'_>,
182182+ extern "C" fn(model: &FznsoModel, constraint: FznsoConstraintIdx) -> FznsoValueRef<'_>,
183183 /// Retrieve the number of annotations on a constraint.
184184 constraint_annotation_len:
185185- extern "C" fn(model: &IpdosModel, constraint: IpdosConstraintIdx) -> usize,
185185+ extern "C" fn(model: &FznsoModel, constraint: FznsoConstraintIdx) -> usize,
186186 /// Retrieve the annotation on a constraint at the given index.
187187 ///
188188 /// The `index` argument must be less than the value returned by
189189 /// `constraint_annotation_len` for the given constraint.
190190 constraint_annotation: extern "C" fn(
191191- model: &IpdosModel,
192192- constraint: IpdosConstraintIdx,
191191+ model: &FznsoModel,
192192+ constraint: FznsoConstraintIdx,
193193 index: usize,
194194- ) -> &IpdosAnnotation,
194194+ ) -> &FznsoAnnotation,
195195196196 /// Request the identifier of the type of objective strategy to be used when
197197 /// solving the model.
198198 ///
199199 /// Note that the function can return a null pointer if the model does not
200200 /// have an objective strategy.
201201- objective_ident: extern "C" fn(model: &IpdosModel) -> *const ffi::c_char,
201201+ objective_ident: extern "C" fn(model: &FznsoModel) -> *const ffi::c_char,
202202 /// Retrieve the argument of the objective strategy.
203203- objective_arg: extern "C" fn(model: &IpdosModel) -> IpdosValueRef<'_>,
203203+ objective_arg: extern "C" fn(model: &FznsoModel) -> FznsoValueRef<'_>,
204204 /// Retrieve the number of annotations on an objective
205205- objective_annotation_len: extern "C" fn(model: &IpdosModel) -> usize,
205205+ objective_annotation_len: extern "C" fn(model: &FznsoModel) -> usize,
206206 /// Retrieve the annotation on the objective at the given index.
207207 ///
208208 /// The `index` argument must be less than the value returned by
209209 /// `objective_annotation_len`.
210210- objective_annotation: extern "C" fn(model: &IpdosModel, index: usize) -> &IpdosAnnotation,
210210+ objective_annotation: extern "C" fn(model: &FznsoModel, index: usize) -> &FznsoAnnotation,
211211212212 /// Retrieve the identifier of an annotation.
213213 ///
214214 /// The returned pointer can be assumed to have the the same lifetime as the
215215 /// annotation reference and must be valid UTF8.
216216- annotation_ident: extern "C" fn(ann: &IpdosAnnotation) -> *const ffi::c_char,
216216+ annotation_ident: extern "C" fn(ann: &FznsoAnnotation) -> *const ffi::c_char,
217217 /// Retrieve the number of arguments of an annotation.
218218- annotation_argument_len: extern "C" fn(ann: &IpdosAnnotation) -> usize,
218218+ annotation_argument_len: extern "C" fn(ann: &FznsoAnnotation) -> usize,
219219 /// Retrieve the value of the annotation's argument at the given index.
220220 ///
221221 /// The `index` argument must be less than the value returned by
222222 /// `annotation_argument_len` for the given annotation.
223223- annotation_argument: extern "C" fn(ann: &IpdosAnnotation, index: usize) -> IpdosValueRef<'_>,
223223+ annotation_argument: extern "C" fn(ann: &FznsoAnnotation, index: usize) -> FznsoValueRef<'_>,
224224}
225225226226#[repr(C)]
···229229///
230230/// The solver can use the included function callbacks to interact with the
231231/// model.
232232-pub struct IpdosModelRef<'a> {
232232+pub struct FznsoModelRef<'a> {
233233 /// The handle to the data of the model instance.
234234- data: &'a IpdosModel,
234234+ data: &'a FznsoModel,
235235 /// Reference to the structure containing the function callbacks used to
236236 /// interact with the model.
237237- methods: &'static IpdosModelMethods,
237237+ methods: &'static FznsoModelMethods,
238238}
239239240240#[repr(C)]
241241#[derive(Clone, Debug)]
242242/// Representation of a type of objective strategies, discerned by its
243243/// identifier and the type of its argument.
244244-pub struct IpdosObjective<'a> {
244244+pub struct FznsoObjective<'a> {
245245 /// The identifier of the objective type.
246246 pub ident: *const ffi::c_char,
247247 /// The type of the expected argument for the constraint type.
248248- pub arg_type: IpdosType,
248248+ pub arg_type: FznsoType,
249249 /// The lifetime for which the `ident` attribute is allocated.
250250 pub lifetime: PhantomData<&'a ()>,
251251}
252252253253#[repr(C)]
254254#[derive(Clone, Debug)]
255255-/// A list of [`IpdosObjective`]s.
255255+/// A list of [`FznsoObjective`]s.
256256///
257257-/// This type is, for example, used to return from [`ipdos_objective_list`].
258258-pub struct IpdosObjectiveList<'a> {
257257+/// This type is, for example, used to return from [`fznso_objective_list`].
258258+pub struct FznsoObjectiveList<'a> {
259259 /// The number of elements in the `options` array.
260260 pub len: usize,
261261 /// An array of option definitions.
262262- pub options: *const IpdosObjective<'a>,
262262+ pub options: *const FznsoObjective<'a>,
263263 /// The lifetime of the `options` attribute.
264264 pub lifetime: PhantomData<&'a ()>,
265265}
···267267#[repr(C)]
268268#[derive(Clone, Debug)]
269269/// The definition of an option that is available to be set for the solver.
270270-pub struct IpdosOption<'a> {
270270+pub struct FznsoOption<'a> {
271271 /// The identifier used to set the option or get the current value of the
272272 /// option.
273273 pub ident: *const ffi::c_char,
274274 /// The type of value that is expected for this option.
275275- pub arg_ty: IpdosValueRef<'a>,
275275+ pub arg_ty: FznsoValueRef<'a>,
276276 /// The default value for this option.
277277- pub arg_def: IpdosType,
277277+ pub arg_def: FznsoType,
278278 /// The lifetime of the `ident` attribute.
279279 pub lifetime: PhantomData<&'a ()>,
280280}
281281282282#[repr(C)]
283283#[derive(Clone, Debug)]
284284-/// A list of [`IpdosOption`]s.
284284+/// A list of [`FznsoOption`]s.
285285///
286286-/// This type is, for example, used to return from [`ipdos_option_list`].
287287-pub struct IpdosOptionList<'a> {
286286+/// This type is, for example, used to return from [`fznso_option_list`].
287287+pub struct FznsoOptionList<'a> {
288288 /// The number of elements in the `options` array.
289289 pub len: usize,
290290 /// An array of option definitions.
291291- pub options: *const IpdosOption<'a>,
291291+ pub options: *const FznsoOption<'a>,
292292 /// The lifetime of the `options` attribute.
293293 pub lifetime: PhantomData<&'a ()>,
294294}
···299299///
300300/// This type is opaque to the user. Only pointers of this type are ever used.
301301///
302302-/// In implementation of the IPDOS interface, a pointer is generally cast to
303303-/// this type, i.e. `(IpdosSolutionData*) my_solution`. A similar cast can be
302302+/// In implementation of the FZnSO interface, a pointer is generally cast to
303303+/// this type, i.e. `(FznsoSolutionData*) my_solution`. A similar cast can be
304304/// used to cast the pointer back to the original type, e.g. `(MySolution*)
305305-/// ipdos_solution`.
306306-pub struct IpdosSolution(ffi::c_void);
305305+/// fznso_solution`.
306306+pub struct FznsoSolution(ffi::c_void);
307307308308#[repr(C)]
309309#[derive(Clone, Debug)]
310310/// A struct containing the function pointers to interact with a
311311-/// [`IpdosSolution`]
312312-pub struct IpdosSolutionMethods {
311311+/// [`FznsoSolution`]
312312+pub struct FznsoSolutionMethods {
313313 /// Function callback to retrieve the value assigned to a decision variable
314314 /// in the solution.
315315- get_value: extern "C" fn(data: &IpdosSolution, decision_index: usize) -> IpdosValueRef<'_>,
315315+ get_value: extern "C" fn(data: &FznsoSolution, decision_index: usize) -> FznsoValueRef<'_>,
316316 /// Function callback to retrieve the statistical information made available
317317 /// by the solver about the search process so far.
318318 get_statistic:
319319- extern "C" fn(data: &IpdosSolution, ident: *const ffi::c_char) -> IpdosValueRef<'_>,
319319+ extern "C" fn(data: &FznsoSolution, ident: *const ffi::c_char) -> FznsoValueRef<'_>,
320320}
321321322322#[repr(C)]
323323#[derive(Clone, Debug)]
324324/// Handle for a solution emitted by the solver.
325325-pub struct IpdosSolutionRef<'a> {
325325+pub struct FznsoSolutionRef<'a> {
326326 /// The data pointer to be the first argument of `get_value`.
327327- data: &'a IpdosSolution,
327327+ data: &'a FznsoSolution,
328328 /// Reference to the structure containing the function callbacks used to
329329 /// interact with the solution.
330330- methods: &'static IpdosSolutionMethods,
330330+ methods: &'static FznsoSolutionMethods,
331331}
332332333333#[repr(transparent)]
···336336///
337337/// This type is opaque to the user. Only pointers of this type are ever used.
338338///
339339-/// In implementation of the IPDOS interface, a pointer is generally cast to
340340-/// this type, i.e. `(IpdosSolver*) my_solver`. A similar cast can be used to
339339+/// In implementation of the FZnSO interface, a pointer is generally cast to
340340+/// this type, i.e. `(FznsoSolver*) my_solver`. A similar cast can be used to
341341/// cast the pointer back to the original type, e.g. `(MySolverType*)
342342-/// ipdos_solver`.
343343-pub struct IpdosSolver(ffi::c_void);
342342+/// fznso_solver`.
343343+pub struct FznsoSolver(ffi::c_void);
344344345345#[repr(C)]
346346#[derive(Clone, Debug)]
347347/// The definition of statistical information that is made available by the
348348/// solver.
349349-pub struct IpdosStatistic<'a> {
349349+pub struct FznsoStatistic<'a> {
350350 /// The identifier used to retrieve the statistical information from the
351351 /// solver or a solution.
352352 pub ident: *const ffi::c_char,
353353 /// The type of value that is expected for this option.
354354- pub ty: IpdosValueRef<'a>,
354354+ pub ty: FznsoValueRef<'a>,
355355 /// Whether the statistical information is available as part of solutions.
356356 pub solution: bool,
357357 /// Whether the statistical information is generally available from the
···363363364364#[repr(C)]
365365#[derive(Clone, Debug)]
366366-/// A list of [`IpdosStatistic`]s.
366366+/// A list of [`FznsoStatistic`]s.
367367///
368368-/// This type is, for example, used to return from [`ipdos_statistic_list`].
369369-pub struct IpdosStatisticList<'a> {
368368+/// This type is, for example, used to return from [`fznso_statistic_list`].
369369+pub struct FznsoStatisticList<'a> {
370370 /// The number of elements in the `stats` array.
371371 pub len: usize,
372372 /// An array of statistical information definitions.
373373- pub stats: *const IpdosStatistic<'a>,
373373+ pub stats: *const FznsoStatistic<'a>,
374374 /// The lifetime of the `stats` attribute.
375375 pub lifetime: PhantomData<&'a ()>,
376376}
377377378378#[repr(C)]
379379#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
380380-/// The status returned by `ipdos_solver_run`, indicating whether the solver
380380+/// The status returned by `fznso_solver_run`, indicating whether the solver
381381/// completed its search.
382382-pub enum IpdosStatus {
382382+pub enum FznsoStatus {
383383 /// The solver explored the full search space and yielded all relevant
384384 /// solutions.
385385- IpdosComplete,
385385+ FznsoComplete,
386386 /// The solver did not explore the full search space due to a timeout or
387387 /// other termination condition. Additional (better) solutions might be
388388 /// possible.
389389- IpdosIncomplete,
389389+ FznsoIncomplete,
390390 /// An error occurred during the solver's execution.
391391 ///
392392- /// [`ipdos_solver_read_error`] can be used to retrieve the error message.
393393- IpdosError,
392392+ /// [`fznso_solver_read_error`] can be used to retrieve the error message.
393393+ FznsoError,
394394}
395395396396#[repr(C)]
397397#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
398398/// Representation of a type to signal and check whether an argument takes the
399399/// correct type.
400400-pub struct IpdosType {
400400+pub struct FznsoType {
401401 /// Whether the type is a list of values.
402402 pub list_of: bool,
403403 /// Whether the argument can be or contain decision variables (represented
···406406 /// Whether expected type is an set of values of the base type.
407407 pub set_of: bool,
408408 /// Whether the expected type is optional (and can take the value of
409409- /// [`IpdosValueKind::IpdosValueAbsent`]).
409409+ /// [`FznsoValueKind::FznsoValueAbsent`]).
410410 pub opt: bool,
411411 /// The expected base type of the argument.
412412- pub base: IpdosTypeBase,
412412+ pub base: FznsoTypeBase,
413413}
414414415415#[repr(C)]
416416#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
417417/// Representation of the base type of a value.
418418-pub enum IpdosTypeBase {
418418+pub enum FznsoTypeBase {
419419 /// Boolean type
420420- IpdosTypeBaseBool,
420420+ FznsoTypeBaseBool,
421421 /// Integer numeric type
422422- IpdosTypeBaseInt,
422422+ FznsoTypeBaseInt,
423423 /// Floating point numeric type
424424- IpdosTypeBaseFloat,
424424+ FznsoTypeBaseFloat,
425425 /// Character string type
426426- IpdosTypeBaseString,
426426+ FznsoTypeBaseString,
427427}
428428429429#[repr(C)]
430430#[derive(Clone, Debug)]
431431-/// A list of [`IpdosType`]s.
431431+/// A list of [`FznsoType`]s.
432432///
433433-/// This type is for example used to return from [`ipdos_decision_list`].
434434-pub struct IpdosTypeList<'a> {
433433+/// This type is for example used to return from [`fznso_decision_list`].
434434+pub struct FznsoTypeList<'a> {
435435 /// The number of elements in the `constraints` array.
436436 pub len: usize,
437437 /// An array of constraint types.
438438- pub types: *const IpdosType,
438438+ pub types: *const FznsoType,
439439 /// The lifetime for which the `types` attribute is allocated.
440440 pub lifetime: PhantomData<&'a ()>,
441441}
···446446///
447447/// This type is opaque to the user. Only pointers of this type are ever used.
448448///
449449-/// In implementation of the IPDOS interface, a pointer is generally cast to
450450-/// this type, e.g. `(IpdosValue*) my_value`. A similar cast can be used to cast
451451-/// the pointer back to the original type, e.g. `(MyValue*) ipdos_value`.
452452-pub struct IpdosValue(ffi::c_void);
449449+/// In implementation of the FZnSO interface, a pointer is generally cast to
450450+/// this type, e.g. `(FznsoValue*) my_value`. A similar cast can be used to cast
451451+/// the pointer back to the original type, e.g. `(MyValue*) fznso_value`.
452452+pub struct FznsoValue(ffi::c_void);
453453454454#[repr(C)]
455455#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
456456-/// Enumerated type used to mark the kind of [`IpdosValue`]. This is used to
457457-/// determine which "get" method in [`IpdosValueMethods`] is safe to call.
458458-pub enum IpdosValueKind {
456456+/// Enumerated type used to mark the kind of [`FznsoValue`]. This is used to
457457+/// determine which "get" method in [`FznsoValueMethods`] is safe to call.
458458+pub enum FznsoValueKind {
459459 /// No value is available.
460460- IpdosValueAbsent,
461461- /// The value is available using [`IpdosValueMethods::get_decision`].
462462- IpdosValueDecision,
463463- /// The value is available using [`IpdosValueMethods::get_constraint`].
464464- IpdosValueConstraint,
465465- /// The value is available using [`IpdosValueMethods::get_bool`].
466466- IpdosValueBool,
467467- /// The value is available using [`IpdosValueMethods::get_int`].
468468- IpdosValueInt,
469469- /// The value is available using [`IpdosValueMethods::get_float`].
470470- IpdosValueFloat,
471471- /// The value is available using [`IpdosValueMethods::get_string`].
472472- IpdosValueString,
460460+ FznsoValueAbsent,
461461+ /// The value is available using [`FznsoValueMethods::get_decision`].
462462+ FznsoValueDecision,
463463+ /// The value is available using [`FznsoValueMethods::get_constraint`].
464464+ FznsoValueConstraint,
465465+ /// The value is available using [`FznsoValueMethods::get_bool`].
466466+ FznsoValueBool,
467467+ /// The value is available using [`FznsoValueMethods::get_int`].
468468+ FznsoValueInt,
469469+ /// The value is available using [`FznsoValueMethods::get_float`].
470470+ FznsoValueFloat,
471471+ /// The value is available using [`FznsoValueMethods::get_string`].
472472+ FznsoValueString,
473473 /// Sets of integers are represented using a range list. The number of
474474- /// ranges is available using [`IpdosValueMethods::len`], and the ranges can
475475- /// be accessed using [`IpdosValueMethods::get_range_int`].
476476- IpdosValueSetInt,
474474+ /// ranges is available using [`FznsoValueMethods::len`], and the ranges can
475475+ /// be accessed using [`FznsoValueMethods::get_range_int`].
476476+ FznsoValueSetInt,
477477 /// Sets of floats are represented using a range list. The number of
478478- /// ranges is available using [`IpdosValueMethods::len`], and the ranges can
479479- /// be accessed using [`IpdosValueMethods::get_range_float`].
480480- IpdosValueSetFloat,
478478+ /// ranges is available using [`FznsoValueMethods::len`], and the ranges can
479479+ /// be accessed using [`FznsoValueMethods::get_range_float`].
480480+ FznsoValueSetFloat,
481481 /// The length of the list can be accessed using
482482- /// [`IpdosValueMethods::len`], and elements in the list can be
483483- /// accessed using [`IpdosValueMethods::get_element`]
484484- IpdosValueList,
482482+ /// [`FznsoValueMethods::len`], and elements in the list can be
483483+ /// accessed using [`FznsoValueMethods::get_element`]
484484+ FznsoValueList,
485485}
486486487487#[repr(C)]
488488#[derive(Clone, Debug)]
489489/// A struct containing the function pointers to interact with a
490490-/// [`IpdosValue`]
491491-pub struct IpdosValueMethods {
490490+/// [`FznsoValue`]
491491+pub struct FznsoValueMethods {
492492 /// Function callback that returns the kind of the value.
493493- kind: extern "C" fn(&IpdosValue) -> IpdosValueKind,
493493+ kind: extern "C" fn(&FznsoValue) -> FznsoValueKind,
494494 /// Function callback that returns the length of the value.
495495 ///
496496- /// In case [`IpdosValueMethods::kind`] returns
497497- /// [`IpdosValueKind::IpdosValueList`], the length is the number of elements
498498- /// in the list, accessible using [`IpdosValueMethods::get_element`].
496496+ /// In case [`FznsoValueMethods::kind`] returns
497497+ /// [`FznsoValueKind::FznsoValueList`], the length is the number of elements
498498+ /// in the list, accessible using [`FznsoValueMethods::get_element`].
499499 ///
500500- /// In case [`IpdosValueMethods::kind`] returns
501501- /// [`IpdosValueKind::IpdosValueSetInt`] or
502502- /// [`IpdosValueKind::IpdosValueSetFloat`], the length is the number of
500500+ /// In case [`FznsoValueMethods::kind`] returns
501501+ /// [`FznsoValueKind::FznsoValueSetInt`] or
502502+ /// [`FznsoValueKind::FznsoValueSetFloat`], the length is the number of
503503 /// ranges in the set, accessible using
504504- /// [`IpdosValueMethods::get_range_int`] or
505505- /// [`IpdosValueMethods::get_range_float`].
504504+ /// [`FznsoValueMethods::get_range_int`] or
505505+ /// [`FznsoValueMethods::get_range_float`].
506506 ///
507507 /// # Panics
508508 ///
509509- /// This function callback may panic if [`IpdosValueMethods::kind`] does not
510510- /// return [`IpdosValueKind::IpdosValueList`],
511511- /// [`IpdosValueKind::IpdosValueSetInt`], or
512512- /// [`IpdosValueKind::IpdosValueSetFloat`].
513513- len: extern "C" fn(&IpdosValue) -> usize,
509509+ /// This function callback may panic if [`FznsoValueMethods::kind`] does not
510510+ /// return [`FznsoValueKind::FznsoValueList`],
511511+ /// [`FznsoValueKind::FznsoValueSetInt`], or
512512+ /// [`FznsoValueKind::FznsoValueSetFloat`].
513513+ len: extern "C" fn(&FznsoValue) -> usize,
514514 /// Function callback that returns the decision variable index contained in
515515 /// the value.
516516 ///
517517 /// # Panics
518518 ///
519519- /// This function callback may panic if [`IpdosValueMethods::kind`] does not
520520- /// return [`IpdosValueKind::IpdosValueDecision`].
521521- get_decision: extern "C" fn(&IpdosValue) -> IpdosDecisionIdx,
519519+ /// This function callback may panic if [`FznsoValueMethods::kind`] does not
520520+ /// return [`FznsoValueKind::FznsoValueDecision`].
521521+ get_decision: extern "C" fn(&FznsoValue) -> FznsoDecisionIdx,
522522 /// Function callback that returns the constraint index contained in the
523523 /// value.
524524 ///
525525 /// # Panics
526526 ///
527527- /// This function callback may panic if [`IpdosValueMethods::kind`] does not
528528- /// return [`IpdosValueKind::IpdosValueConstraint`].
529529- get_constraint: extern "C" fn(&IpdosValue) -> IpdosConstraintIdx,
527527+ /// This function callback may panic if [`FznsoValueMethods::kind`] does not
528528+ /// return [`FznsoValueKind::FznsoValueConstraint`].
529529+ get_constraint: extern "C" fn(&FznsoValue) -> FznsoConstraintIdx,
530530 /// Function callback that returns the integer value contained in the value.
531531 ///
532532 /// # Panics
533533 ///
534534- /// This function callback may panic if [`IpdosValueMethods::kind`] does not
535535- /// return [`IpdosValueKind::IpdosValueInt`].
536536- get_int: extern "C" fn(&IpdosValue) -> i64,
534534+ /// This function callback may panic if [`FznsoValueMethods::kind`] does not
535535+ /// return [`FznsoValueKind::FznsoValueInt`].
536536+ get_int: extern "C" fn(&FznsoValue) -> i64,
537537 /// Function callback that returns the floating point value contained in the
538538 /// value.
539539 ///
540540 /// # Panics
541541 ///
542542- /// This function callback may panic if [`IpdosValueMethods::kind`] does not
543543- /// return [`IpdosValueKind::IpdosValueFloat`].
544544- get_float: extern "C" fn(&IpdosValue) -> f64,
542542+ /// This function callback may panic if [`FznsoValueMethods::kind`] does not
543543+ /// return [`FznsoValueKind::FznsoValueFloat`].
544544+ get_float: extern "C" fn(&FznsoValue) -> f64,
545545 /// Function callback that returns the string pointer value contained in the
546546 /// value.
547547 ///
548548 /// # Panics
549549 ///
550550- /// This function callback may panic if [`IpdosValueMethods::kind`] does not
551551- /// return [`IpdosValueKind::IpdosValueString`].
552552- get_string: extern "C" fn(&IpdosValue) -> *const ffi::c_char,
550550+ /// This function callback may panic if [`FznsoValueMethods::kind`] does not
551551+ /// return [`FznsoValueKind::FznsoValueString`].
552552+ get_string: extern "C" fn(&FznsoValue) -> *const ffi::c_char,
553553 /// Function callback that returns the Boolean value contained in the value.
554554 ///
555555 /// # Panics
556556 ///
557557- /// This function callback may panic if [`IpdosValueMethods::kind`] does not
558558- /// return [`IpdosValueKind::IpdosValueBool`].
559559- get_bool: extern "C" fn(&IpdosValue) -> bool,
557557+ /// This function callback may panic if [`FznsoValueMethods::kind`] does not
558558+ /// return [`FznsoValueKind::FznsoValueBool`].
559559+ get_bool: extern "C" fn(&FznsoValue) -> bool,
560560 /// Function callback that returns a range from a range list representing
561561 /// the integer set contained in the value.
562562 ///
563563 /// # Panics
564564 ///
565565- /// This function callback may panic if [`IpdosValueMethods::kind`] does not
566566- /// return [`IpdosValueKind::IpdosValueSetInt`].
567567- get_range_int: extern "C" fn(&IpdosValue, index: usize) -> [i64; 2],
565565+ /// This function callback may panic if [`FznsoValueMethods::kind`] does not
566566+ /// return [`FznsoValueKind::FznsoValueSetInt`].
567567+ get_range_int: extern "C" fn(&FznsoValue, index: usize) -> [i64; 2],
568568 /// Function callback that returns a range from a range list representing
569569 /// the floating point set contained in the value.
570570 ///
571571 /// # Panics
572572 ///
573573- /// This function callback may panic if [`IpdosValueMethods::kind`] does not
574574- /// return [`IpdosValueKind::IpdosValueSetFloat`].
575575- get_range_float: extern "C" fn(&IpdosValue, index: usize) -> [f64; 2],
573573+ /// This function callback may panic if [`FznsoValueMethods::kind`] does not
574574+ /// return [`FznsoValueKind::FznsoValueSetFloat`].
575575+ get_range_float: extern "C" fn(&FznsoValue, index: usize) -> [f64; 2],
576576 /// Function callback that returns an element from the list contained in the
577577 /// value.
578578 ///
579579 /// # Panics
580580 ///
581581- /// This function callback may panic if [`IpdosValueMethods::kind`] does not
582582- /// return [`IpdosValueKind::IpdosValueList`].
583583- get_element: extern "C" fn(&IpdosValue, index: usize) -> IpdosValueRef<'_>,
581581+ /// This function callback may panic if [`FznsoValueMethods::kind`] does not
582582+ /// return [`FznsoValueKind::FznsoValueList`].
583583+ get_element: extern "C" fn(&FznsoValue, index: usize) -> FznsoValueRef<'_>,
584584}
585585586586#[repr(C)]
···589589///
590590/// The caller can use the `get_value` function to retrieve the value of the
591591/// used decision variables.
592592-pub struct IpdosValueRef<'a> {
592592+pub struct FznsoValueRef<'a> {
593593 /// The data pointer to be the first argument of `get_value`.
594594- data: &'a IpdosValue,
594594+ data: &'a FznsoValue,
595595 /// Reference to the structure containing the function callbacks used to
596596 /// interact with the value.
597597- methods: &'static IpdosValueMethods,
597597+ methods: &'static FznsoValueMethods,
598598}
599599600600#[cfg(test)]
601601mod tests {
602602- use crate::{IpdosModelRef, IpdosSolutionRef, IpdosType, IpdosValueRef};
602602+ use crate::{FznsoModelRef, FznsoSolutionRef, FznsoType, FznsoValueRef};
603603604604 #[test]
605605 fn memory() {
606606- assert_eq!(size_of::<IpdosModelRef>(), size_of::<u128>());
607607- assert_eq!(size_of::<IpdosSolutionRef>(), size_of::<u128>());
608608- assert_eq!(size_of::<IpdosType>(), size_of::<u64>());
609609- assert_eq!(size_of::<IpdosValueRef>(), size_of::<u128>());
606606+ assert_eq!(size_of::<FznsoModelRef>(), size_of::<u128>());
607607+ assert_eq!(size_of::<FznsoSolutionRef>(), size_of::<u128>());
608608+ assert_eq!(size_of::<FznsoType>(), size_of::<u64>());
609609+ assert_eq!(size_of::<FznsoValueRef>(), size_of::<u128>());
610610 }
611611}