mirror of
https://github.com/Mercury-Language/mercury.git
synced 2026-04-16 18:03:36 +00:00
Discussion of these changes can be found on the Mercury developers
mailing list archives from June 2018.
COPYING.LIB:
Add a special linking exception to the LGPL.
*:
Update references to COPYING.LIB.
Clean up some minor errors that have accumulated in copyright
messages.
147 lines
5.8 KiB
Mathematica
147 lines
5.8 KiB
Mathematica
%---------------------------------------------------------------------------%
|
|
% vim: ts=4 sw=4 et ft=mercury
|
|
%---------------------------------------------------------------------------%
|
|
% Copyright (C) 2016, 2018 The Mercury team.
|
|
% This file is distributed under the terms specified in COPYING.LIB.
|
|
%---------------------------------------------------------------------------%
|
|
%
|
|
% This module defines the state of the constraint solver.
|
|
%
|
|
% For each solver variable, the state records what values it may ever have,
|
|
% and for each of those values, it records whether that value has been
|
|
% ruled out yet, and if yes, by *what* constraint or other means it was
|
|
% ruled out. We record such "why not" information because we can use it
|
|
% to generate useful error messages if the constraint solver finds an
|
|
% inconsistency.
|
|
%
|
|
|
|
:- module grade_lib.grade_state.
|
|
:- interface.
|
|
|
|
:- import_module grade_lib.grade_spec.
|
|
|
|
:- import_module list.
|
|
:- import_module map.
|
|
|
|
%---------------------------------------------------------------------------%
|
|
|
|
:- type solver_var_map == map(solver_var_id, solver_var).
|
|
|
|
:- type solver_var
|
|
---> solver_var(
|
|
% The number of all the values that this variable may ever
|
|
% be bound to.
|
|
sv_cnt_all :: int,
|
|
|
|
% The number of all the values that it is still possible
|
|
% for this variable variable to take. This will be sv_cnt_all,
|
|
% minus the number of values that have already been ruled out
|
|
% for this variable.
|
|
sv_cnt_possible :: int,
|
|
|
|
% A list of the values that this variable may ever have,
|
|
% specifying for each of those values whether it is still
|
|
% possible or not, and if not, why not.
|
|
sv_values :: list(solver_var_value)
|
|
).
|
|
|
|
:- type solver_var_value
|
|
---> solver_var_value(
|
|
svv_id :: solver_var_value_id,
|
|
svv_is_possible :: solver_var_value_possible
|
|
).
|
|
|
|
:- type solver_var_value_possible
|
|
---> is_possible
|
|
; not_possible(
|
|
np_why :: not_possible_why
|
|
).
|
|
|
|
:- type not_possible_why
|
|
---> npw_config
|
|
% The variable cannot have this value, because autoconfiguration
|
|
% has selected another value.
|
|
|
|
; npw_user
|
|
% The variable cannot have this value, because the user
|
|
% has requested another value for this variable.
|
|
|
|
; npw_requirement(requirement_application)
|
|
% The variable cannot have this value, due to the application
|
|
% of the given requirement in the given manner.
|
|
|
|
; npw_labeling.
|
|
% The variable cannot have this value, because labelling has
|
|
% selected another value for this variable.
|
|
|
|
:- type requirement_application
|
|
---> requirement_application(
|
|
% The given value of the solver variable was ruled out
|
|
% by the application of the requirement with this id
|
|
% and description, and in this direction.
|
|
ra_req_id :: requirement_id,
|
|
ra_req_desc :: string,
|
|
ra_dir :: req_dir
|
|
).
|
|
|
|
:- type req_dir
|
|
---> narrow_then_values
|
|
; delete_if_value.
|
|
|
|
%---------------------------------------------------------------------------%
|
|
%
|
|
% The requirement type is an extension of the requirement_spec type
|
|
% defined in grade_spec.m. It is defined for efficient processing, not
|
|
% easy readability of the requirement specifications, and it associates
|
|
% a unique id with each requirement, for use in "why not" records
|
|
% in the solver var map.
|
|
%
|
|
|
|
:- type requirement_id
|
|
---> requirement_id(int).
|
|
|
|
:- type requirement
|
|
---> requirement(
|
|
req_id :: requirement_id,
|
|
req_desc :: string,
|
|
req_if_solver_var :: solver_var_id,
|
|
req_if_value :: solver_var_value_id,
|
|
req_then_solver_var :: solver_var_id,
|
|
req_then_values :: list(solver_var_value_id)
|
|
).
|
|
|
|
%---------------------------------------------------------------------------%
|
|
%
|
|
% The state of the solver.
|
|
%
|
|
% The most frequently updated part is the si_solver_var_map field, which
|
|
% records which values are (still) possible for each solver variable.
|
|
%
|
|
% The si_reqs field lists all the requirements (constraints) that may
|
|
% still be useful for propagation. Initially, this field will contain
|
|
% all the requirements transliterated from init_requirement_specs,
|
|
% but when we use a requirement for propagation, we may notice that
|
|
% the requirement won't be needed ever again. If that happens, we delete
|
|
% the requirement from the solver_info, so we won't waste time trying
|
|
% to apply it again.
|
|
%
|
|
% The si_vars_priority field will initially list all the solver variables
|
|
% in order of their priority for labelling. If two variables both have
|
|
% more than one possible value, labelling will pick the one that occurs
|
|
% earlier in this list. When labelling finds that a variable has only one
|
|
% possible value, it knows it won't be interested in the variable ever again,
|
|
% so it removes such variables from the si_vars_priority field, to make
|
|
% future labelling steps faster.
|
|
%
|
|
|
|
:- type solver_info
|
|
---> solver_info(
|
|
si_reqs :: list(requirement),
|
|
si_vars_priority :: list(solver_var_id),
|
|
si_solver_var_map :: solver_var_map
|
|
).
|
|
|
|
%---------------------------------------------------------------------------%
|
|
:- end_module grade_lib.grade_state.
|
|
%---------------------------------------------------------------------------%
|