···33# Build the Huub solver
44build:
55 cargo build
66- cbindgen --config crates/ipdos_protocol/cbindgen.toml --crate ipdos_protocol --output crates/ipdos_protocol/ipdos_protocol.h
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
7889# Check the codebase using all CI linters
910check:
+44
c/ipdos_solver_template.c
···11+#include "ipdos_types.h"
22+33+// Returns the list of available constraint that can be added to the solver.
44+IpdosConstraintList ipdos_constraint_list(void);
55+66+// Returns the list of types for which decision variable can be created by the
77+// solver.
88+IpdosTypeList ipdos_decision_list(void);
99+1010+// Returns the list of available objective that can be achieved by the solver.
1111+IpdosObjectiveList ipdos_objective_list(void);
1212+1313+// Returns the list of available options that can be set of the solver.
1414+IpdosOptionList ipdos_option_list(void);
1515+1616+// Create a new solver instance
1717+IpdosSolver *ipdos_solver_create(void);
1818+1919+// 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);
2424+2525+// 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+IpdosValue ipdos_solver_option_get(const IpdosSolver *solver, const char *ident);
3030+3131+// 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, IpdosValue value);
3636+3737+// 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,
4343+ void *context,
4444+ void (*read_error)(void *context, const char *error));
···11-#ifndef ipdos_protocol_h
22-#define ipdos_protocol_h
11+#ifndef ipdos_types_h
22+#define ipdos_types_h
3344-#include <stdarg.h>
55-#include <stdbool.h>
66-#include <stdint.h>
77-#include <stdlib.h>
44+#include <stdbool>
55+#include <stdint>
8697// The status returned by `ipdos_solver_run`, indicating whether the solver
108// completed its search.
···5351 IpdosValueList,
5452} IpdosValueKind;
55535454+// The handle to a the data of a solution instance.
5555+//
5656+// This type is opaque to the user. Only pointers of this type are ever used.
5757+//
5858+// In implementation of the IPDOS interface, a pointer is generally cast to
5959+// this type, i.e. `(IpdosSolutionData*) my_solution`. A similar cast can be
6060+// used to cast the pointer back to the original type, e.g. `(MySolution*)
6161+// ipdos_solution`.
6262+typedef void IpdosAnnotation;
6363+5664// Representation of a type to signal and check whether an argument takes the
5765// correct type.
5866typedef struct IpdosType {
···9199 const struct IpdosConstraintType *constraints;
92100} IpdosConstraintList;
931019494-// A list of [`IpdosType`]s.
102102+// The handle of a model instance.
95103//
9696-// This type is for example used to return from [`ipdos_decision_list`].
9797-typedef struct IpdosTypeList {
9898- // The number of elements in the `constraints` array.
9999- uint64_t len;
100100- // An array of constraint types.
101101- const struct IpdosType *types;
102102-} IpdosTypeList;
103103-104104-// Representation of a type of objective strategies, discerned by its
105105-// identifier and the type of its argument.
106106-typedef struct IpdosObjective {
107107- // The identifier of the objective type.
108108- const char *ident;
109109- // The type of the expected argument for the constraint type.
110110- struct IpdosType arg_type;
111111-} IpdosObjective;
112112-113113-// A list of [`IpdosObjective`]s.
104104+// This type is opaque to the user. Only pointers of this type are ever used.
114105//
115115-// This type is, for example, used to return from [`ipdos_objective_list`].
116116-typedef struct IpdosObjectiveList {
117117- // The number of elements in the `options` array.
118118- uint64_t len;
119119- // An array of option definitions.
120120- const struct IpdosObjective *options;
121121-} IpdosObjectiveList;
106106+// In implementation of the IPDOS interface, a pointer is generally cast to
107107+// this type, i.e. `(IpdosModelData*) my_model`. A similar cast can be used to
108108+// cast the pointer back to the original type, e.g. `(MyModel*) ipdos_model`.
109109+typedef void IpdosModel;
122110123111// The storage of the value content of a [`IpdosValue`].
124112typedef union IpdosValueContent {
···180168 union IpdosValueContent content;
181169} IpdosValue;
182170183183-// The definition of an option that is available to be set for the solver.
184184-typedef struct IpdosOption {
185185- // The identifier used to set the option or get the current value of the
186186- // option.
187187- const char *ident;
188188- // The type of value that is expected for this option.
189189- struct IpdosValue arg_ty;
190190- // The default value for this option.
191191- struct IpdosType arg_def;
192192-} IpdosOption;
193193-194194-// A list of [`IpdosOption`]s.
195195-//
196196-// This type is, for example, used to return from [`ipdos_option_list`].
197197-typedef struct IpdosOptionList {
198198- // The number of elements in the `options` array.
199199- uint64_t len;
200200- // An array of option definitions.
201201- const struct IpdosOption *options;
202202-} IpdosOptionList;
203203-204204-// The handle to a solver instance.
205205-//
206206-// This type is opaque to the user. Only pointers of this type are ever used.
207207-//
208208-// In implementation of the IPDOS interface, a pointer is generally cast to
209209-// this type, i.e. `(IpdosSolver*) my_solver`. A similar cast can be used to
210210-// cast the pointer back to the original type, e.g. `(MySolverType*)
211211-// ipdos_solver`.
212212-typedef void IpdosSolver;
213213-214214-// The handle of a model instance.
215215-//
216216-// This type is opaque to the user. Only pointers of this type are ever used.
217217-//
218218-// In implementation of the IPDOS interface, a pointer is generally cast to
219219-// this type, i.e. `(IpdosModelData*) my_model`. A similar cast can be used to
220220-// cast the pointer back to the original type, e.g. `(MyModel*) ipdos_model`.
221221-typedef void IpdosModel;
222222-223223-// The handle to a the data of a solution instance.
224224-//
225225-// This type is opaque to the user. Only pointers of this type are ever used.
226226-//
227227-// In implementation of the IPDOS interface, a pointer is generally cast to
228228-// this type, i.e. `(IpdosSolutionData*) my_solution`. A similar cast can be
229229-// used to cast the pointer back to the original type, e.g. `(MySolution*)
230230-// ipdos_solution`.
231231-typedef void IpdosAnnotation;
232232-233171// A struct containing the function pointers to interact with theIpdosModel`
234172typedef struct IpdosModelMethods {
235173 // Returns the current number of model layers currently contained in the
···374312 const struct IpdosModelMethods *methods;
375313} IpdosModelRef;
376314315315+// Representation of a type of objective strategies, discerned by its
316316+// identifier and the type of its argument.
317317+typedef struct IpdosObjective {
318318+ // The identifier of the objective type.
319319+ const char *ident;
320320+ // The type of the expected argument for the constraint type.
321321+ struct IpdosType arg_type;
322322+} IpdosObjective;
323323+324324+// A list of [`IpdosObjective`]s.
325325+//
326326+// This type is, for example, used to return from [`ipdos_objective_list`].
327327+typedef struct IpdosObjectiveList {
328328+ // The number of elements in the `options` array.
329329+ uint64_t len;
330330+ // An array of option definitions.
331331+ const struct IpdosObjective *options;
332332+} IpdosObjectiveList;
333333+334334+// The definition of an option that is available to be set for the solver.
335335+typedef struct IpdosOption {
336336+ // The identifier used to set the option or get the current value of the
337337+ // option.
338338+ const char *ident;
339339+ // The type of value that is expected for this option.
340340+ struct IpdosValue arg_ty;
341341+ // The default value for this option.
342342+ struct IpdosType arg_def;
343343+} IpdosOption;
344344+345345+// A list of [`IpdosOption`]s.
346346+//
347347+// This type is, for example, used to return from [`ipdos_option_list`].
348348+typedef struct IpdosOptionList {
349349+ // The number of elements in the `options` array.
350350+ uint64_t len;
351351+ // An array of option definitions.
352352+ const struct IpdosOption *options;
353353+} IpdosOptionList;
354354+377355// The handle to a the data of a solution instance.
378356//
379357// This type is opaque to the user. Only pointers of this type are ever used.
···384362// ipdos_solution`.
385363typedef void IpdosSolution;
386364387387-// Returns the list of available constraint that can be added to the solver.
388388-struct IpdosConstraintList ipdos_constraint_list(void);
389389-390390-// Returns the list of types for which decision variable can be created by the
391391-// solver.
392392-struct IpdosTypeList ipdos_decision_list(void);
393393-394394-// Returns the list of available objective that can be achieved by the solver.
395395-struct IpdosObjectiveList ipdos_objective_list(void);
396396-397397-// Returns the list of available options that can be set of the solver.
398398-struct IpdosOptionList ipdos_option_list(void);
399399-400400-// Create a new solver instance
401401-IpdosSolver *ipdos_solver_create(void);
402402-403403-// Free a solver instance, releasing all resources associated with it.
365365+// Structure used to represent a solution emitted by the solver.
404366//
405405-// The pointer to the solver instance will be invalid after this function has
406406-// been called.
407407-void ipdos_solver_free(IpdosSolver *solver);
367367+// The caller can use the `get_value` function to retrieve the value of the
368368+// used decision variables.
369369+typedef struct IpdosSolutionRef {
370370+ // The data pointer to be the first argument of `get_value`.
371371+ const IpdosSolution *data;
372372+ // Function callback to retrieve the value assigned to a decision variable
373373+ // in the solution.
374374+ struct IpdosValue (*get_value)(const IpdosSolution *data, uint64_t decision_index);
375375+} IpdosSolutionRef;
408376409409-// Get the current value of an option for the solver.
377377+// The handle to a solver instance.
410378//
411411-// Note that this is only valid to be called with options named by
412412-// `ipdos_option_list`.
413413-struct IpdosValue ipdos_solver_option_get(const IpdosSolver *solver, const char *ident);
414414-415415-// Set the current value of an option for the solver.
379379+// This type is opaque to the user. Only pointers of this type are ever used.
416380//
417417-// Note that this is only valid to be called with options named by
418418-// `ipdos_option_list`, and the value must be of the correct type.
419419-bool ipdos_solver_option_set(IpdosSolver *solver, const char *ident, struct IpdosValue value);
381381+// In implementation of the IPDOS interface, a pointer is generally cast to
382382+// this type, i.e. `(IpdosSolver*) my_solver`. A similar cast can be used to
383383+// cast the pointer back to the original type, e.g. `(MySolverType*)
384384+// ipdos_solver`.
385385+typedef void IpdosSolver;
420386421421-// Read an error message from the solver.
387387+// A list of [`IpdosType`]s.
422388//
423423-// This function is expected to be called after solver interactions signal an
424424-// error has occurred. For example, if [`ipdos_solver_run`] returns
425425-// [`IpdosError`] or [`ipdos_solver_push`] returns `false`.
426426-void ipdos_solver_read_error(IpdosSolver *solver,
427427- void *context,
428428- void (*read_error)(void *context, const char *error));
429429-430430-// Run the solver with the given model
431431-enum IpdosStatus ipdos_solver_run(IpdosSolver *solver,
432432- struct IpdosModelRef model,
433433- void *context,
434434- void (*on_solution)(void *context, const IpdosSolution *solution));
389389+// This type is for example used to return from [`ipdos_decision_list`].
390390+typedef struct IpdosTypeList {
391391+ // The number of elements in the `constraints` array.
392392+ uint64_t len;
393393+ // An array of constraint types.
394394+ const struct IpdosType *types;
395395+} IpdosTypeList;
435396436436-#endif /* ipdos_protocol_h */
397397+#endif /* ipdos_types_h */
···11-//! IPDOS Protocol
11+//! IPDOS Protocol Types
22//!
33-//! This crate defines the IPDOS protocol, which allows the incremental usage of
44-//! solvers that can solve decision and optimization problems. The goal of the
55-//! interface is to easily use different solvers in a unified way.
33+//! This crate defines the types of the IPDOS 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).
6777-use core::fmt;
88-use std::{ffi, marker::PhantomData, ptr::slice_from_raw_parts};
88+#![no_std]
99+use core::{ffi, fmt, marker::PhantomData, ptr::slice_from_raw_parts};
9101011#[repr(transparent)]
1112#[derive(Debug)]
···453454 IpdosValueString,
454455 /// The value is stored in `list_value`.
455456 IpdosValueList,
456456-}
457457-458458-#[unsafe(no_mangle)]
459459-/// Returns the list of available constraint that can be added to the solver.
460460-pub extern "C" fn ipdos_constraint_list() -> IpdosConstraintList<'static> {
461461- unimplemented!()
462462-}
463463-464464-#[unsafe(no_mangle)]
465465-/// Returns the list of types for which decision variable can be created by the
466466-/// solver.
467467-pub extern "C" fn ipdos_decision_list() -> IpdosTypeList<'static> {
468468- unimplemented!()
469469-}
470470-471471-#[unsafe(no_mangle)]
472472-/// Returns the list of available objective that can be achieved by the solver.
473473-pub extern "C" fn ipdos_objective_list() -> IpdosObjectiveList<'static> {
474474- unimplemented!()
475475-}
476476-477477-#[unsafe(no_mangle)]
478478-/// Returns the list of available options that can be set of the solver.
479479-pub extern "C" fn ipdos_option_list() -> IpdosOptionList<'static> {
480480- unimplemented!()
481481-}
482482-483483-#[unsafe(no_mangle)]
484484-/// Create a new solver instance
485485-pub extern "C" fn ipdos_solver_create() -> Box<IpdosSolver> {
486486- unimplemented!()
487487-}
488488-489489-/// Free a solver instance, releasing all resources associated with it.
490490-///
491491-/// The pointer to the solver instance will be invalid after this function has
492492-/// been called.
493493-#[unsafe(no_mangle)]
494494-pub extern "C" fn ipdos_solver_free(solver: Box<IpdosSolver>) {
495495- let _ = solver;
496496- unimplemented!()
497497-}
498498-499499-#[unsafe(no_mangle)]
500500-/// Get the current value of an option for the solver.
501501-///
502502-/// Note that this is only valid to be called with options named by
503503-/// `ipdos_option_list`.
504504-pub extern "C" fn ipdos_solver_option_get(
505505- solver: &IpdosSolver,
506506- ident: *const ffi::c_char,
507507-) -> IpdosValue<'_> {
508508- let _ = solver;
509509- let _ = ident;
510510- unimplemented!()
511511-}
512512-513513-#[unsafe(no_mangle)]
514514-/// Set the current value of an option for the solver.
515515-///
516516-/// Note that this is only valid to be called with options named by
517517-/// `ipdos_option_list`, and the value must be of the correct type.
518518-pub extern "C" fn ipdos_solver_option_set(
519519- solver: &mut IpdosSolver,
520520- ident: *const ffi::c_char,
521521- value: IpdosValue<'_>,
522522-) -> bool {
523523- let _ = solver;
524524- let _ = ident;
525525- let _ = value;
526526- unimplemented!()
527527-}
528528-529529-#[unsafe(no_mangle)]
530530-/// Read an error message from the solver.
531531-///
532532-/// This function is expected to be called after solver interactions signal an
533533-/// error has occurred. For example, if [`ipdos_solver_run`] returns
534534-/// [`IpdosError`] or [`ipdos_solver_push`] returns `false`.
535535-pub extern "C" fn ipdos_solver_read_error(
536536- solver: &mut IpdosSolver,
537537- context: &mut ffi::c_void,
538538- read_error: extern "C" fn(context: &mut ffi::c_void, error: *const ffi::c_char),
539539-) {
540540- let _ = solver;
541541- let _ = context;
542542- let _ = read_error;
543543- unimplemented!()
544544-}
545545-546546-#[unsafe(no_mangle)]
547547-/// Run the solver with the given model
548548-pub extern "C" fn ipdos_solver_run(
549549- solver: &mut IpdosSolver,
550550- model: IpdosModelRef,
551551- context: &mut ffi::c_void,
552552- on_solution: extern "C" fn(context: &mut ffi::c_void, solution: &IpdosSolution),
553553-) -> IpdosStatus {
554554- let _ = solver;
555555- let _ = model;
556556- let _ = context;
557557- let _ = on_solution;
558558- unimplemented!()
559457}
560458561459impl fmt::Debug for IpdosValue<'_> {
···11+//! IPDOS Protocol Solver Template
22+//!
33+//! This crate defines the solver functionality to be implemented IPDOS
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
77+//! solver libraries (as DLLs).
88+99+use core::ffi;
1010+1111+use ipdos_types::{
1212+ IpdosConstraintList, IpdosModelRef, IpdosObjectiveList, IpdosOptionList, IpdosSolution,
1313+ IpdosSolver, IpdosStatus, IpdosTypeList, IpdosValue,
1414+};
1515+1616+#[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> {
1919+ unimplemented!()
2020+}
2121+2222+#[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> {
2626+ unimplemented!()
2727+}
2828+2929+#[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> {
3232+ unimplemented!()
3333+}
3434+3535+#[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> {
3838+ unimplemented!()
3939+}
4040+4141+#[unsafe(no_mangle)]
4242+/// Create a new solver instance
4343+pub extern "C" fn ipdos_solver_create() -> Box<IpdosSolver> {
4444+ unimplemented!()
4545+}
4646+4747+/// Free a solver instance, releasing all resources associated with it.
4848+///
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: Box<IpdosSolver>) {
5353+ let _ = solver;
5454+ unimplemented!()
5555+}
5656+5757+#[unsafe(no_mangle)]
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,
6464+ ident: *const ffi::c_char,
6565+) -> IpdosValue<'_> {
6666+ let _ = solver;
6767+ let _ = ident;
6868+ unimplemented!()
6969+}
7070+7171+#[unsafe(no_mangle)]
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,
7878+ ident: *const ffi::c_char,
7979+ value: IpdosValue<'_>,
8080+) -> bool {
8181+ let _ = solver;
8282+ let _ = ident;
8383+ let _ = value;
8484+ unimplemented!()
8585+}
8686+8787+#[unsafe(no_mangle)]
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,
9595+ context: &mut ffi::c_void,
9696+ read_error: extern "C" fn(context: &mut ffi::c_void, error: *const ffi::c_char),
9797+) {
9898+ let _ = solver;
9999+ let _ = context;
100100+ let _ = read_error;
101101+ unimplemented!()
102102+}
103103+104104+#[unsafe(no_mangle)]
105105+/// Run the solver with the given model
106106+///
107107+/// cbindgen:no-export
108108+pub extern "C" fn ipdos_solver_run(
109109+ solver: &mut IpdosSolver,
110110+ model: IpdosModelRef,
111111+ context: &mut ffi::c_void,
112112+ on_solution: extern "C" fn(context: &mut ffi::c_void, solution: &IpdosSolution),
113113+) -> IpdosStatus {
114114+ let _ = solver;
115115+ let _ = model;
116116+ let _ = context;
117117+ let _ = on_solution;
118118+ unimplemented!()
119119+}