123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180(* Copyright (C) 2013, Thomas Leonard
See the README file for details, or visit http://0install.net. *)(** Some useful abstract module types. *)moduletypeCORE_MODEL=sig(** To use the solver with a particular packaging system (e.g. 0install), you need
to provide an implementation of this module to map your system's concepts on to
the solver's. *)moduleRole:sig(** A role that needs to be filled by a single implementation.
If two dependencies require the same role then they will both
get the same implementation.
This could be the package name, although 0install also includes
whether you want source code or a binary in the role. *)typetvalpp:Format.formatter->t->unitvalcompare:t->t->intend(** An [impl] is something that can fill a [Role.t] (e.g. a particular version of
a package). *)typeimpl(** A [command] is an entry-point provided by an implementation.
Using a command may require extra dependencies (for example, a "test" command
might depend on a test runner). *)typecommand(** An identifier for a command within a role.
Note: It might not be necessary to use any commands - we could instead
treat the command name as an optional part of the role, and treat each
command as a separate impl instead. *)typecommand_name=privatestring(** A dependency indicates that an impl or command requires another role to be filled. *)typedependencytypedep_info={dep_role:Role.t;(* If the dependency is [`Essential] then its role must be filled.
Otherwise, we just prefer to fill it if possible.
A [`Restricts] dependency does not cause the solver to try to fill a role, it just
adds restrictions if it is used for some other reason. *)dep_importance:[`Essential|`Recommended|`Restricts];(* Any commands on [dep_role] required by this dependency. *)dep_required_commands:command_namelist;}(* The top-level requirements from the user. *)typerequirements={role:Role.t;command:command_nameoption;}(** Get an implementation's dependencies.
The dependencies should be ordered with the most important first.
The solver will prefer to select the best possible version of an earlier
dependency, even if that means selecting a worse version of a later one
([restricts_only] dependencies are ignored for this).
An implementation or command can also bind to itself.
e.g. "test" command that requires its own "run" command.
We also return all such required commands. *)valrequires:Role.t->impl->dependencylist*command_namelistvaldep_info:dependency->dep_info(** As [requires], but for commands. *)valcommand_requires:Role.t->command->dependencylist*command_namelistvalget_command:impl->command_name->commandoptionendmoduletypeSOLVER_INPUT=sig(** This defines what the solver sees (hiding the raw XML, etc). *)includeCORE_MODEL(** Information provided to the solver about a role. *)typerole_information={replacement:Role.toption;(** Another role that conflicts with this one. *)impls:impllist;(** Candidates to fill the role. *)}(** A restriction limits which implementations can fill a role. *)typerestriction(** The solver will avoid selections with mixed machine groups.
This is useful if e.g. the CPU supports 32-bit and 64-bit programs,
but we can't mix them in a single process. The string simply has
to be unique for each group (e.g. "32" and "64"). *)typemachine_group=privatestringvalpp_impl:Format.formatter->impl->unitvalpp_command:Format.formatter->command->unit(** The list of candidates to fill a role. *)valimplementations:Role.t->role_information(** Restrictions on how the role is filled *)valrestrictions:dependency->restrictionlistvalmeets_restriction:impl->restriction->boolvalmachine_group:impl->machine_groupoption(** There can be only one implementation in each conflict class. *)typeconflict_class=privatestringvalconflict_class:impl->conflict_classlist(** {2 The following are used for diagnostics only} *)(** The reason why the model rejected an implementation before it got to the solver.
For example, the implementation was a Windows binary but the host is Linux. *)typerejection(** Get the candidates which were rejected for a role (and not passed to the solver),
as well as any general notes and warnings not tied to a particular impl. *)valrejects:Role.t->(impl*rejection)list*stringlist(** Used to sort the results. *)valcompare_version:impl->impl->intvalpp_version:Format.formatter->impl->unit(** Get any user-specified restrictions affecting a role.
These are used to filter out implementations before they get to the solver. *)valuser_restrictions:Role.t->restrictionoption(** A detailed identifier for the implementation. In 0install, this is the version
number and part of the hash. *)valpp_impl_long:Format.formatter->impl->unitvalformat_machine:impl->stringvalstring_of_restriction:restriction->stringvaldescribe_problem:impl->rejection->string(** A dummy implementation, used to get diagnostic information if the solve fails.
It satisfies all requirements, even conflicting ones. *)valdummy_impl:implendmoduletypeSELECTIONS=sig(** Some selections previously produced by a solver. *)includeCORE_MODELmoduleRoleMap:Map.Swithtypekey=Role.ttypetvalto_map:t->implRoleMap.tvalget_selected:Role.t->t->imploptionvalselected_commands:impl->command_namelistvalrequirements:t->requirementsendmoduletypeSOLVER_RESULT=sig(** The result of running the solver.
Unlike the plain [SELECTIONS] type, this type can relate the selections back
to the solver inputs, which is useful to provide diagnostics and the GUI. *)moduleInput:SOLVER_INPUTincludeSELECTIONSwithmoduleRole=Input.Roleandtypecommand=Input.commandandtypedependency=Input.dependencyandtypecommand_name=Input.command_nameandtypedep_info=Input.dep_infoandtyperequirements=Input.requirementsvalunwrap:impl->Input.impl(** Get diagnostics-of-last-resort. *)valexplain:t->Role.t->stringend