Files
mercury/grade_lib/grade_state.m
Mark Brown d465fa53cb Update the COPYING.LIB file and references to it.
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.
2018-06-09 17:43:12 +10:00

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.
%---------------------------------------------------------------------------%