[m-rev.] for review: drop support for automatic solver type initialisation

Julien Fischer juliensf at csse.unimelb.edu.au
Wed Oct 31 01:56:42 AEDT 2007


For review by Ralph.

Estimated hours taken: 10
Branches: main

Remove support for automatic initialisation of solver types from the language.
This is being done because:

* the current implementation of automatic initialisation means we cannot
   support polymorphic solver types, e.g. you cannot have the type foo(bar)
   where:
   		:- solver type foo(T).
 		:- solver type bar.

* the current initialisation strategy is fairly ad-hoc anyway; in particular
   it has a tendency to unnecessarily change the determinism of procedures.

* mode error messages are often quite poor because of the interaction between
   automatic initialisation and impure code.

* automatic initialisation is not used in practice.  All of the
   G12 solver libraries that use solver types recommend explicitly
   initialising solver variables.

This change removes support for automatic solver initialisation from the
language.  The code for supporting it remains in the implementation, but
it is now dependent upon the developer-only `--solver-type-auto-init'
option.

As a transitional measure the compiler will still accept
`initialisation is ...' attributes in solver type definitions even when
`--no-solver-type-auto-init' is enabled.  After this change has bootstrapped,
and the relevant updates have been made to the G12 solver libraries, this
will be changed so that `initialisation is ...' attributes are considered
a syntax error unless `--solver-type-auto-init' is enabled.

doc/reference_manual.texi:
 	Document that solver type definitions no longer allow initialisation
 	predicates to be supplied.  (The section documenting initialisation
 	predicates has been commented out rather than deleted since the
 	implementation of automatic initialisation still exists.)

 	Remove the section documenting the restrictions on polymorphic
 	solver types.  These restrictions no longer apply in the absence
 	of automatic initialisation.

compiler/options.m:
 	Add a new developer-only option, `--solver-type-auto-init', that
 	controls whether automatic initialisation of solver variables is
 	allowed (for those solver types that have initialisation predicates
 	specified.)

compiler/prog_data.m:
 	Add a type that represents whether a solver type allows automatic
 	initialisation or not.

 	Extend the solver_type_details structure to allow initialisation
 	predicates to be optional.

compiler/prog_io.m:
 	Allow initialisation predicates to be optional in solver type
 	definitions.

compiler/modes.m:
compiler/modecheck_call.m:
compiler/modecheck_unify.m:
 	Only insert calls to solver type initialisation predicates if
 	the solver type has an initialisation predicate and the
 	developer-only option `--solver-type-auto-init' is enabled.

compiler/unify_proc.m:
 	Handle the situation where a solver type does not have an
 	initialise predicate.

compiler/add_special_pred.m:
 	Only add initialisation special predicates for those solver
 	types whose definition provides an initialisation predicate.

compiler/mode_info.m:
 	Add a utility predicate that tests whether the support for
 	automatic solver type initialisation is enabled.

compiler/type_util.m:
 	Add a predicate that tests whether a type is a solver type
 	that supports automatic initialisation.

 	Add an XXX comment about such types and abstract equivalence
 	types.

compiler/mercury_to_mercury.m:
 	Conform to the above changes.

compiler/special_pred.m:
 	Fix some typos.

samples/solver_types/eqneq.m:
 	Delete the `initialisation is ...' from the definition of the solver
 	type eqneq/1.

tests/hard_coded/Mercury.options:
 	Enable `--solver-type-auto-init' for the solver_construction_init_test
 	test.

tests/hard_coded/solver_build_call.m:
tests/invalid/any_pass_as_ground.m:
 	Don't use automatic solver variable initialisation in these
 	test cases.

tests/invalid/partial_implied_mode.err_exp:
 	Conform to the above changes in the mode analyser.

tests/valid/Mercury.options:
 	Compile some tests cases with `--solver-type-auto-init' enabled.

Julien.

Index: compiler/add_special_pred.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/add_special_pred.m,v
retrieving revision 1.21
diff -u -r1.21 add_special_pred.m
--- compiler/add_special_pred.m	2 Oct 2007 07:41:47 -0000	1.21
+++ compiler/add_special_pred.m	30 Oct 2007 14:48:58 -0000
@@ -172,16 +172,14 @@
                      TypeCtor, Body, Context, Status, !ModuleInfo)
              )
          ),
-        (
-            type_util.type_body_is_solver_type(!.ModuleInfo, Body)
-        ->
+        ( type_is_solver_type_with_auto_init(!.ModuleInfo, Type) ->
              add_special_pred(spec_pred_init, TVarSet, Type, TypeCtor, Body,
                  Context, Status, !ModuleInfo)
          ;
              true
          )
      ;
-        ( type_util.type_body_is_solver_type(!.ModuleInfo, Body) ->
+        ( type_is_solver_type_with_auto_init(!.ModuleInfo, Type) ->
              SpecialPredIds = [spec_pred_unify, spec_pred_compare,
                  spec_pred_init]
          ;
@@ -226,17 +224,16 @@
              SpecialPredId = spec_pred_index
          ;
              SpecialPredId = spec_pred_compare,
-            ( TypeBody ^ du_type_usereq = yes(_) ->
-                    % The compiler generated comparison
-                    % procedure prints an error message,
-                    % since comparisons of types with
-                    % user-defined equality are not
-                    % allowed. We get the runtime system
-                    % invoke this procedure instead of
-                    % printing the error message itself,
-                    % because it is easier to generate
-                    % a good error message in Mercury code
-                    % than in C code.
+            (
+                % The compiler generated comparison procedure prints an error
+                % message, since comparisons of types with user-defined
+                % equality are not allowed.
+                % We get the runtime system to invoke this procedure instead
+                % of printing the error message itself, because it is easier
+                % to generate a good error message in Mercury code than in
+                % C code.
+                TypeBody ^ du_type_usereq = yes(_)
+            ->
                  do_add_special_pred_for_real(SpecialPredId, TVarSet, Type,
                      TypeCtor, TypeBody, Context, Status0, !ModuleInfo)
              ;
@@ -244,12 +241,13 @@
              )
          ;
              SpecialPredId = spec_pred_init,
-            ( type_is_solver_type(!.ModuleInfo, Type) ->
+            ( type_is_solver_type_with_auto_init(!.ModuleInfo, Type) ->
                  do_add_special_pred_for_real(SpecialPredId, TVarSet, Type,
                      TypeCtor, TypeBody, Context, Status0, !ModuleInfo)
              ;
-                unexpected(this_file, "add_special_pred: " ++
-                    "attempt to add initialise pred for non-solver type")
+                unexpected(this_file, "add_special_pred: "
+                    ++ "attempt to add initialise pred for non-solver type "
+                    ++ "or solver type without automatic initialisation.")
              )
          )
      ).
@@ -296,7 +294,7 @@
      ;
          PredInfo1 = PredInfo0
      ),
-    unify_proc.generate_clause_info(SpecialPredId, Type, TypeBody,
+    generate_clause_info(SpecialPredId, Type, TypeBody,
          Context, !.ModuleInfo, ClausesInfo),
      pred_info_set_clauses_info(ClausesInfo, PredInfo1, PredInfo2),
      pred_info_get_markers(PredInfo2, Markers2),
Index: compiler/mercury_to_mercury.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/mercury_to_mercury.m,v
retrieving revision 1.319
diff -u -r1.319 mercury_to_mercury.m
--- compiler/mercury_to_mercury.m	27 Aug 2007 06:22:13 -0000	1.319
+++ compiler/mercury_to_mercury.m	30 Oct 2007 14:48:58 -0000
@@ -1905,12 +1905,17 @@
          solver_type_details::in, io::di, io::uo) is det.

  mercury_output_solver_type_details(TVarSet,
-        solver_type_details(RepresentationType, InitPred, GroundInst, AnyInst,
+        solver_type_details(RepresentationType, HowToInit, GroundInst, AnyInst,
          MutableItems), !IO) :-
      io.write_string("representation is ", !IO),
      mercury_output_type(TVarSet, no, RepresentationType, !IO),
-    io.write_string(",\n\t\tinitialisation is ", !IO),
-    mercury_output_bracketed_sym_name(InitPred, !IO),
+    (
+        HowToInit = solver_init_explicit
+    ;
+        HowToInit = solver_init_automatic(InitPred),
+        io.write_string(",\n\t\tinitialisation is ", !IO),
+        mercury_output_bracketed_sym_name(InitPred, !IO)
+    ),
      varset.init(EmptyInstVarSet),
      io.write_string(",\n\t\tground is ", !IO),
      mercury_output_inst(GroundInst, EmptyInstVarSet, !IO),
Index: compiler/mode_info.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/mode_info.m,v
retrieving revision 1.95
diff -u -r1.95 mode_info.m
--- compiler/mode_info.m	14 Aug 2007 01:52:28 -0000	1.95
+++ compiler/mode_info.m	30 Oct 2007 14:48:58 -0000
@@ -308,6 +308,12 @@

  :- pred mode_info_may_init_solver_vars(mode_info::in) is semidet.

+    % Succeeds if automatic initialisation of solver variables is
+    % supported.  This is only the case if the developer-only option
+    % `--solver-type-auto-init' is enabled.
+    %
+:- pred mode_info_solver_init_is_supported(mode_info::in) is semidet.
+
  %-----------------------------------------------------------------------------%
  %-----------------------------------------------------------------------------%

@@ -429,6 +435,7 @@
      % Please try to keep the size of this structure down to eight fields.
      % Even one more field will cause the Boehm allocator to round up the size
      % of each memory cell to 16 words.
+    %
  :- type mode_info
      --->    mode_info(
                  mi_module_info              :: module_info,
@@ -824,6 +831,13 @@

  %-----------------------------------------------------------------------------%

+mode_info_solver_init_is_supported(ModeInfo) :-
+    mode_info_get_module_info(ModeInfo, ModuleInfo),
+    module_info_get_globals(ModuleInfo, Globals),
+    globals.lookup_bool_option(Globals, solver_type_auto_init, yes).
+
+%-----------------------------------------------------------------------------%
+
  :- func this_file = string.

  this_file = "mode_info.m".
Index: compiler/modecheck_call.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/modecheck_call.m,v
retrieving revision 1.80
diff -u -r1.80 modecheck_call.m
--- compiler/modecheck_call.m	14 Aug 2007 01:52:28 -0000	1.80
+++ compiler/modecheck_call.m	30 Oct 2007 14:48:58 -0000
@@ -407,17 +407,20 @@

  modecheck_end_of_call(ProcInfo, Purity, ProcArgModes, ArgVars0, ArgOffset,
          InstVarSub, ArgVars, ExtraGoals, !ModeInfo) :-
+    mode_info_get_module_info(!.ModeInfo, ModuleInfo),
      mode_info_get_may_init_solver_vars(!.ModeInfo, MayInitSolverVars),

      % Since we can't reschedule impure goals, we must allow the initialisation
      % of free solver type args if necessary in impure calls.
-    ( Purity = purity_impure ->
+    ( 
+        Purity = purity_impure,
+        mode_info_solver_init_is_supported(!.ModeInfo)
+    ->
          mode_info_set_may_init_solver_vars(may_init_solver_vars, !ModeInfo)
      ;
          true
      ),

-    mode_info_get_module_info(!.ModeInfo, ModuleInfo),
      mode_list_get_initial_insts(ModuleInfo, ProcArgModes, InitialInsts0),
      inst_list_apply_substitution(InstVarSub, InitialInsts0, InitialInsts),
      mode_list_get_final_insts(ModuleInfo, ProcArgModes, FinalInsts0),
Index: compiler/modecheck_unify.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/modecheck_unify.m,v
retrieving revision 1.119
diff -u -r1.119 modecheck_unify.m
--- compiler/modecheck_unify.m	27 Aug 2007 06:22:14 -0000	1.119
+++ compiler/modecheck_unify.m	30 Oct 2007 14:48:58 -0000
@@ -130,13 +130,14 @@
      % insert initialisation calls at this point, then do so to allow
      % scheduling of the unification.
      (
+        mode_info_solver_init_is_supported(!.ModeInfo),
          mode_info_may_init_solver_vars(!.ModeInfo),
          InstOfX0   = free,
          InstOfY0   = free,
-        VarType    = VarTypes^elem(X),
-        type_util.type_is_solver_type(ModuleInfo0, VarType)
+        VarType    = VarTypes ^ elem(X),
+        type_is_solver_type_with_auto_init(ModuleInfo0, VarType)
      ->
-        modes.construct_initialisation_call(X, VarType, any_inst,
+        construct_initialisation_call(X, VarType, any_inst,
              context_init, no, InitXGoal, !ModeInfo),
          MaybeInitX = yes(InitXGoal),
          instmap.set(X, any_inst, InstMap0, InstMap),
Index: compiler/modes.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/modes.m,v
retrieving revision 1.360
diff -u -r1.360 modes.m
--- compiler/modes.m	14 Aug 2007 01:52:29 -0000	1.360
+++ compiler/modes.m	30 Oct 2007 14:48:58 -0000
@@ -1185,12 +1185,21 @@
          ;
              !:Changed = yes,
              (
-                % If this is a solver type with inst `free' that should have
-                % inst `any' then insert a call to the appropriate
-                % initialisation predicate.
+                % Insert a call to the appropriate solver type initialisation
+                % predicate if:
+                %
+                % (a) this is a solver type with inst `free' that should
+                %     have inst `any'.
+                % 
+                % (b) this is a solver type that allows automatic
+                %     initialisation.
+                %
+                % (c) the option `--solver-type-auto-init' is enabled.
+                %
                  inst_match.inst_is_free(ModuleInfo, VarInst),
                  inst_match.inst_is_any(ModuleInfo, Inst),
-                type_util.type_is_solver_type(ModuleInfo, Type)
+                type_is_solver_type_with_auto_init(ModuleInfo, Type), 
+                mode_info_solver_init_is_supported(!.ModeInfo)
              ->
                  prepend_initialisation_call(Var, Type, VarInst, !Goal,
                      !ModeInfo)
@@ -1988,11 +1997,11 @@
      mode_info_set_delay_info(DelayInfo3, !ModeInfo),

      % Otherwise try scheduling by inserting solver initialisation calls
-    % where necessary.
+    % where necessary (although only if `--solver-type-auto-init' is enabled).
+    %
      modecheck_delayed_solver_goals(ConjType, Goals2,
          DelayedGoals0, DelayedGoals, RevImpurityErrors0, RevImpurityErrors,
          !ModeInfo, !IO),
-
      Goals = Goals1 ++ Goals2,

      mode_info_get_errors(!.ModeInfo, NewErrors),
@@ -2203,18 +2212,22 @@
      impurity_errors::in, impurity_errors::out,
      mode_info::in, mode_info::out, io::di, io::uo) is det.

-modecheck_delayed_solver_goals(ConjType, Goals, DelayedGoals0, DelayedGoals,
+modecheck_delayed_solver_goals(ConjType, Goals, !DelayedGoals,
          !ImpurityErrors, !ModeInfo, !IO) :-
-    % Try to handle any unscheduled goals by inserting solver
-    % initialisation calls, aiming for a deterministic schedule.
-    modecheck_delayed_goals_try_det(ConjType, DelayedGoals0, DelayedGoals1,
-        Goals0, !ImpurityErrors, !ModeInfo, !IO),
-
-    % Try to handle any unscheduled goals by inserting solver
-    % initialisation calls, aiming for *any* workable schedule.
-    modecheck_delayed_goals_eager(ConjType, DelayedGoals1, DelayedGoals,
-        Goals1, !ImpurityErrors, !ModeInfo, !IO),
-    Goals = Goals0 ++ Goals1.
+    ( mode_info_solver_init_is_supported(!.ModeInfo) ->
+        % Try to handle any unscheduled goals by inserting solver
+        % initialisation calls, aiming for a deterministic schedule.
+        modecheck_delayed_goals_try_det(ConjType, !DelayedGoals,
+            Goals0, !ImpurityErrors, !ModeInfo, !IO),
+
+        % Try to handle any unscheduled goals by inserting solver
+        % initialisation calls, aiming for *any* workable schedule.
+        modecheck_delayed_goals_eager(ConjType, !DelayedGoals,
+            Goals1, !ImpurityErrors, !ModeInfo, !IO),
+        Goals = Goals0 ++ Goals1
+    ;
+        Goals = []
+    ).

      % We may still have some unscheduled goals.  This may be because some
      % initialisation calls are needed to turn some solver type vars
@@ -2289,7 +2302,7 @@
              =>
                  (
                      map.lookup(VarTypes, Var, VarType),
-                    type_util.type_is_solver_type(ModuleInfo, VarType)
+                    type_is_solver_type_with_auto_init(ModuleInfo, VarType)
                  )
              )
          ->
@@ -3157,7 +3170,8 @@
              mode_info_get_errors(!.ModeInfo, ModeErrors),
              ModeErrors = [],
              mode_info_may_init_solver_vars(!.ModeInfo),
-            type_util.type_is_solver_type(ModuleInfo0, VarType)
+            mode_info_solver_init_is_supported(!.ModeInfo),
+            type_is_solver_type_with_auto_init(ModuleInfo0, VarType)
          ->
              % Create code to initialize the variable to inst `any',
              % by calling the solver type's initialisation predicate.
@@ -3214,7 +3228,7 @@
          MaybeCallUnifyContext, InitVarGoal, !ModeInfo) :-
      (
          type_to_ctor_and_args(VarType, TypeCtor, _TypeArgs),
-        PredName = special_pred.special_pred_name(spec_pred_init, TypeCtor),
+        PredName = special_pred_name(spec_pred_init, TypeCtor),
          (
              TypeCtor = type_ctor(qualified(ModuleName, _TypeName), _Arity)
          ;
Index: compiler/options.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/options.m,v
retrieving revision 1.597
diff -u -r1.597 options.m
--- compiler/options.m	25 Oct 2007 06:53:43 -0000	1.597
+++ compiler/options.m	30 Oct 2007 14:48:58 -0000
@@ -477,6 +477,10 @@
      ;       size_region_disj_snapshot
      ;       size_region_commit_entry

+    ;       solver_type_auto_init
+            % Insert calls to solver type initialisation predicates when
+            % the inst of solver type variables changes from free to any.
+
      % Code generation options
      ;       low_level_debug
      ;       table_debug
@@ -1210,7 +1214,8 @@
      size_region_ite_snapshot            -   int(4),
      size_region_disj_protect            -   int(0),
      size_region_disj_snapshot           -   int(4),
-    size_region_commit_entry            -   int(1)
+    size_region_commit_entry            -   int(1),
+    solver_type_auto_init               -   bool(no)
  ]).
  option_defaults_2(code_gen_option, [
      % Code Generation Options
@@ -1994,6 +1999,7 @@
  long_option("size-region-disj-protect",     size_region_disj_protect).
  long_option("size-region-disj-snapshot",    size_region_disj_snapshot).
  long_option("size-region-commit-entry",     size_region_commit_entry).
+long_option("solver-type-auto-init",        solver_type_auto_init).

  % code generation options
  long_option("low-level-debug",      low_level_debug).
@@ -4088,6 +4094,11 @@
  %       "--size-region-disj-protect"
  %       "--size-region-disj-snapshot"
  %       "--size-region-commit-entry"
+
+        % This is a developer only option.
+%       "--solver-type-auto-init",
+%       "(This option is not for general use.)",
+%       Allow automatic initialisation of solver types.
      ]).

  :- pred options_help_code_generation(io::di, io::uo) is det.
Index: compiler/prog_data.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/prog_data.m,v
retrieving revision 1.196
diff -u -r1.196 prog_data.m
--- compiler/prog_data.m	28 Sep 2007 03:17:13 -0000	1.196
+++ compiler/prog_data.m	30 Oct 2007 14:48:58 -0000
@@ -1194,7 +1194,7 @@
  :- type solver_type_details
      --->    solver_type_details(
                  representation_type :: mer_type,
-                init_pred           :: init_pred,
+                init_pred           :: solver_type_init,
                  ground_inst         :: mer_inst,
                  any_inst            :: mer_inst,
                  mutable_items       :: list(item)
@@ -1207,6 +1207,17 @@
      %
  :- type init_pred   ==  sym_name.

+    % What sort of initialisation, if any, is required by a solver type?
+    %
+:- type solver_type_init
+    --->    solver_init_explicit
+            % The user will explicitly insert calls to initialise solver
+            % variables of this type in their code.
+ 
+    ;       solver_init_automatic(init_pred).
+            % The mode analyser should insert calls to `init_pred' in order
+            % to initialise solver variables of this type.
+
      % An equality_pred specifies the name of a user-defined predicate
      % used for equality on a type.  See the chapter on them in the
      % Mercury Language Reference Manual.
Index: compiler/prog_io.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/prog_io.m,v
retrieving revision 1.283
diff -u -r1.283 prog_io.m
--- compiler/prog_io.m	31 Jul 2007 05:02:12 -0000	1.283
+++ compiler/prog_io.m	30 Oct 2007 14:48:58 -0000
@@ -2375,7 +2375,7 @@
              IsSolverType = solver_type,
              (
                  RepresentationIs = yes(RepnType),
-                InitialisationIs = yes(InitPred),
+                InitialisationIs = MaybeInitialisation,
                  GroundIs         = MaybeGroundInst,
                  AnyIs            = MaybeAnyInst,
                  EqualityIs       = MaybeEqPred,
@@ -2400,8 +2400,16 @@
                      MaybeMutableItems = no,
                      MutableItems = []
                  ),
-                MaybeSolverTypeDetails = yes(solver_type_details(
-                    RepnType, InitPred, GroundInst, AnyInst, MutableItems)),
+                (
+                    MaybeInitialisation = yes(InitPred),
+                    HowToInit = solver_init_automatic(InitPred)
+                ;
+                    MaybeInitialisation = no,
+                    HowToInit = solver_init_explicit
+                ), 
+                SolverTypeDetails = solver_type_details(
+                    RepnType, HowToInit, GroundInst, AnyInst, MutableItems),
+                MaybeSolverTypeDetails = yes(SolverTypeDetails),
                  (
                      MaybeEqPred = no,
                      MaybeCmpPred = no
@@ -2419,12 +2427,6 @@
                      "`representation' attribute",
                  Result = error2([Msg - WhereTerm])
              ;
-                InitialisationIs = no
-            ->
-                Msg = "solver type definitions must have an" ++
-                    "`initialisation' attribute",
-                Result = error2([Msg - WhereTerm])
-            ;
                 unexpected(this_file, "make_maybe_where_details_2: " ++
                      "shouldn't have reached this point! (1)")
              )
Index: compiler/special_pred.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/special_pred.m,v
retrieving revision 1.69
diff -u -r1.69 special_pred.m
--- compiler/special_pred.m	30 May 2007 08:16:01 -0000	1.69
+++ compiler/special_pred.m	30 Oct 2007 14:48:58 -0000
@@ -80,7 +80,7 @@

      % A compiler-generated predicate only needs type checking if
      % (a) it is a user-defined equality pred, or
-    % (b) it is the unification or comparison predicate for an existially
+    % (b) it is the unification or comparison predicate for an existentially
      %     quantified type, or
      % (c) it is the initialisation predicate for a solver type.
      %
@@ -293,7 +293,7 @@
  %-----------------------------------------------------------------------------%

      % The compiler generates the rtti for the builtins when we are on the
-    % non C backends. We don't generate the rtti on the C backends as the
+    % non-C backends. We don't generate the rtti on the C backends as the
      % runtime contains references to this rtti so the rtti must be defined
      % in the runtime not the library.
      %
Index: compiler/type_util.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/type_util.m,v
retrieving revision 1.184
diff -u -r1.184 type_util.m
--- compiler/type_util.m	2 Oct 2007 04:32:49 -0000	1.184
+++ compiler/type_util.m	30 Oct 2007 14:48:58 -0000
@@ -97,6 +97,12 @@
  :- pred type_body_has_solver_type_details(module_info::in,
      hlds_type_body::in, solver_type_details::out) is semidet.

+    % Succeeds if this type is a solver type that has an initialisation
+    % predicate specified by the user.
+    %
+:- pred type_is_solver_type_with_auto_init(module_info::in, mer_type::in)
+    is semidet.
+
  :- pred is_solver_type(module_info::in, mer_type::in) is semidet.

      % Succeed if the type body is for a solver type.
@@ -491,6 +497,28 @@
      list.foldl(type_definitely_has_no_user_defined_eq_pred_2(ModuleInfo),
          ArgTypes, !SeenTypes).

+type_is_solver_type_with_auto_init(ModuleInfo, Type) :-
+    type_to_type_defn_body(ModuleInfo, Type, TypeBody),
+    (
+        TypeBody = hlds_solver_type(_, _),
+        ActualType = Type
+    ;
+        % XXX the current implementation doesn't provide enough information
+        % to determine whether abstract solver types support automatic
+        % initialisation or not.  In the absence of such information we
+        % assume that they do not.  Since we don't officially support
+        % automatic initialisation anyway this shouldn't be too much of a
+        % problem.  (In the event that we do re-add some form of support for 
+        % automatic solver initialisation then we will need to make sure
+        % that this information ends up in interface files somehow.)
+        TypeBody = hlds_abstract_type(solver_type),
+        fail
+    ;
+        TypeBody = hlds_eqv_type(ActualType)
+    ),
+    type_has_solver_type_details(ModuleInfo, ActualType, SolverTypeDetails),
+    SolverTypeDetails ^ init_pred = solver_init_automatic(_).
+
  type_is_solver_type(ModuleInfo, Type) :-
      type_to_type_defn_body(ModuleInfo, Type, TypeBody),
      (
Index: compiler/unify_proc.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/unify_proc.m,v
retrieving revision 1.193
diff -u -r1.193 unify_proc.m
--- compiler/unify_proc.m	25 Sep 2007 04:56:43 -0000	1.193
+++ compiler/unify_proc.m	30 Oct 2007 14:48:58 -0000
@@ -713,15 +713,22 @@
  generate_initialise_proc_body(_Type, TypeBody, X, Context, Clause, !Info) :-
      info_get_module_info(!.Info, ModuleInfo),
      (
-        type_util.type_body_has_solver_type_details(ModuleInfo,
-            TypeBody, SolverTypeDetails)
+        type_body_has_solver_type_details(ModuleInfo, TypeBody,
+            SolverTypeDetails)
      ->
          % Just generate a call to the specified predicate, which is
          % the user-defined equality pred for this type.
          % (The pred_id and proc_id will be figured out by type checking
          % and mode analysis.)
-
-        InitPred = SolverTypeDetails ^ init_pred,
+        %
+        HowToInit = SolverTypeDetails ^ init_pred,
+        (
+            HowToInit = solver_init_automatic(InitPred)
+        ;
+            HowToInit = solver_init_explicit,
+            unexpected(this_file, "generating initialise pred. for " ++
+                "solver type that does not have automatic initialisation.")
+        ),
          PredId = invalid_pred_id,
          ModeId = invalid_proc_id,
          Call = plain_call(PredId, ModeId, [X], not_builtin, no, InitPred),
@@ -738,8 +745,8 @@
          make_fresh_named_var_from_type(EqvType, "PreCast_HeadVar", 1, X0,
              !Info),
          type_to_ctor_det(EqvType, TypeCtor),
-        PredName = special_pred.special_pred_name(spec_pred_init, TypeCtor),
-        hlds_module.module_info_get_name(ModuleInfo, ModuleName),
+        PredName = special_pred_name(spec_pred_init, TypeCtor),
+        module_info_get_name(ModuleInfo, ModuleName),
          TypeCtor = type_ctor(TypeSymName, _TypeArity),
          sym_name_get_module_name(TypeSymName, ModuleName, TypeModuleName),
          InitPred = qualified(TypeModuleName, PredName),
Index: doc/reference_manual.texi
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/doc/reference_manual.texi,v
retrieving revision 1.410
diff -u -r1.410 reference_manual.texi
--- doc/reference_manual.texi	18 Oct 2007 06:19:05 -0000	1.410
+++ doc/reference_manual.texi	30 Oct 2007 14:48:58 -0000
@@ -2245,7 +2245,6 @@
  * Solver type definitions::
  * Implementing solver types::
  * Solver types and negated contexts::
-* Polymorphic solver types::
  @end menu

  Solver types are an experimental addition to the language supporting the
@@ -2305,7 +2304,6 @@
  @example
  :- solver type solver_type
          where   representation   is representation_type,
-                initialisation   is initialisation_pred,
                  ground           is ground_inst,
                  any              is any_inst,
                  constraint_store is mutable_decls,
@@ -2313,8 +2311,7 @@
                  comparison       is comparison_pred.
  @end example

-The @samp{representation} and @samp{initialisation} attributes are mandatory
-(@samp{initialization} is allowed as a synonym for @samp{initialisation}),
+The @samp{representation} attribute is mandatory
  @samp{ground_inst} and @samp{any_inst} default to @samp{ground},
  @samp{mutable_decls} is either a single mutable declaration
  (@pxref{Module-local mutable variables})
@@ -2337,17 +2334,22 @@
  comparison predicates for the @code{solver_type}.
  @end itemize

-The @code{initialisation_pred} is the name of a predicate defined in the same
-module as the solver type, with the following signature:
-
- at example
-:- pred initialisation_pred(solver_type::out(any)) is det.
- at end example
-
-Calls to this predicate are inserted automatically by the compiler when a
- at code{free} @code{solver_type} variable has to be given inst @code{any}.
-(The initialisation predicate is responsible for registering the new, unbound
-variable with the corresponding constraint solver state.)
+ at c XXX The following paragraph describes the old support for automatic
+ at c     initialisation of solver types.  We no longer officially support
+ at c     automatic initialisation as part of the language but the compiler
+ at c     still contains the code necessary to implement it.
+ at c
+ at c The @code{initialisation_pred} is the name of a predicate defined in the
+ at c same module as the solver type, with the following signature:
+ at c 
+ at c @example
+ at c :- pred initialisation_pred(solver_type::out(any)) is det.
+ at c @end example
+ at c 
+ at c Calls to this predicate are inserted automatically by the compiler when a
+ at c @code{free} @code{solver_type} variable has to be given inst @code{any}.
+ at c (The initialisation predicate is responsible for registering the new,
+ at c unbound variable with the corresponding constraint solver state.)

  The @code{ground_inst} is the inst associated with
  @code{representation_type} values denoting @code{ground}
@@ -2464,13 +2466,6 @@
  lambda expressions to be @code{impure}, even if they would normally be
  considered pure.

- at node Polymorphic solver types
- at subsection Polymorphic solver types
-
-Under the current design, the compiler does not have enough information to
-initialise variables belonging to polymorphic parameters that are themselves
-expected to be solver types.  At some point we intend to lift this restriction.
-
  @node Modes
  @chapter Modes

Index: samples/solver_types/eqneq.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/samples/solver_types/eqneq.m,v
retrieving revision 1.1
diff -u -r1.1 eqneq.m
--- samples/solver_types/eqneq.m	15 Feb 2007 00:27:17 -0000	1.1
+++ samples/solver_types/eqneq.m	30 Oct 2007 14:48:58 -0000
@@ -58,14 +58,11 @@
  :- import_module set.
  :- import_module univ.

-
-
      % An eqneq is represented by an eqneq_id, which is a key in the
      % mutable constraint_store map.
      %
  :- solver type eqneq(T) where
      representation is eqneq_id,
-    initialisation is new,
      equality is eq.

  :- type eqneq_id == int.
Index: tests/hard_coded/Mercury.options
===================================================================
RCS file: /home/mercury/mercury1/repository/tests/hard_coded/Mercury.options,v
retrieving revision 1.28
diff -u -r1.28 Mercury.options
--- tests/hard_coded/Mercury.options	29 Aug 2007 02:53:13 -0000	1.28
+++ tests/hard_coded/Mercury.options	30 Oct 2007 14:48:58 -0000
@@ -59,6 +59,13 @@
  MCFLAGS-opt_dup_bug	=	-O2 --optimize-dups --optimize-frames
  MCFLAGS-redoip_clobber	=	--no-inlining
  MCFLAGS-rnd		=	-O6
+
+# This test checks that calls to initialisation predicates are correctly
+# added to construction unifications, so it only works if automatic
+# initialisation of solver types is enabled.
+#
+MCFLAGS-solver_construction_init_test = --solver-type-auto-init
+
  MCFLAGS-split_c_files	=	--trace rep
  MCFLAGS-switch_detect	=	--halt-at-warn
  # The trace_goal_1 and trace_goal_2 test cases differ only in that
Index: tests/hard_coded/solver_build_call.m
===================================================================
RCS file: /home/mercury/mercury1/repository/tests/hard_coded/solver_build_call.m,v
retrieving revision 1.2
diff -u -r1.2 solver_build_call.m
--- tests/hard_coded/solver_build_call.m	8 Nov 2005 06:42:02 -0000	1.2
+++ tests/hard_coded/solver_build_call.m	30 Oct 2007 14:48:58 -0000
@@ -48,13 +48,14 @@
  :- pred solve_problem(int::out) is semidet.

  solve_problem(Solution) :-
+    init(B),
+    init(C),
      post_constraint( B \/ -C),
      post_constraint(-B \/  C),
      solve([B, C], Solution).

  :- solver type st
-    where   representation is int,
-            initialisation is init.
+    where   representation is int.


  :- pred init(st::oa) is det.
Index: tests/invalid/any_passed_as_ground.m
===================================================================
RCS file: /home/mercury/mercury1/repository/tests/invalid/any_passed_as_ground.m,v
retrieving revision 1.4
diff -u -r1.4 any_passed_as_ground.m
--- tests/invalid/any_passed_as_ground.m	29 Mar 2006 08:08:05 -0000	1.4
+++ tests/invalid/any_passed_as_ground.m	30 Oct 2007 14:48:58 -0000
@@ -42,7 +42,8 @@

  :- pred p(list(pair(int, st))::oa) is det.

-p([1 - _, 2 - _, 3 - _]).
+p([1 - A, 2 - B, 3 - C]) :-
+    i(A), i(B), i(C).

  %-----------------------------------------------------------------------------%
  %-----------------------------------------------------------------------------%
Index: tests/invalid/partial_implied_mode.err_exp
===================================================================
RCS file: /home/mercury/mercury1/repository/tests/invalid/partial_implied_mode.err_exp,v
retrieving revision 1.13
diff -u -r1.13 partial_implied_mode.err_exp
--- tests/invalid/partial_implied_mode.err_exp	21 May 2007 04:23:26 -0000	1.13
+++ tests/invalid/partial_implied_mode.err_exp	30 Oct 2007 14:48:58 -0000
@@ -9,14 +9,14 @@
  partial_implied_mode.m:033:   ground, bound(partial_implied_mode2.absol(ground,
  partial_implied_mode.m:033:   ground))))))':
  partial_implied_mode.m:033:   mode error in unification of `HeadVar__1' and
-partial_implied_mode.m:033:   `partial_implied_mode2.physic_quantity(V_13, V_4,
-partial_implied_mode.m:033:   V_14)'.
+partial_implied_mode.m:033:   `partial_implied_mode2.physic_quantity(V_11, V_4,
+partial_implied_mode.m:033:   V_12)'.
  partial_implied_mode.m:033:   Variable `HeadVar__1' has instantiatedness
  partial_implied_mode.m:033:   `unique(partial_implied_mode2.physic_quantity(ground,
  partial_implied_mode.m:033:   free, unique(partial_implied_mode2.absol(free,
  partial_implied_mode.m:033:   free))))',
-partial_implied_mode.m:033:   term `partial_implied_mode2.physic_quantity(V_13,
-partial_implied_mode.m:033:   V_4, V_14)' has instantiatedness
+partial_implied_mode.m:033:   term `partial_implied_mode2.physic_quantity(V_11,
+partial_implied_mode.m:033:   V_4, V_12)' has instantiatedness
  partial_implied_mode.m:033:   `partial_implied_mode2.physic_quantity(
  partial_implied_mode.m:033:     free,
  partial_implied_mode.m:033:     ground,
Index: tests/valid/Mercury.options
===================================================================
RCS file: /home/mercury/mercury1/repository/tests/valid/Mercury.options,v
retrieving revision 1.39
diff -u -r1.39 Mercury.options
--- tests/valid/Mercury.options	13 Aug 2007 03:02:01 -0000	1.39
+++ tests/valid/Mercury.options	30 Oct 2007 14:48:58 -0000
@@ -90,6 +90,10 @@
  MCFLAGS-simplify_bug2		= -O3
  MCFLAGS-simplify_bug		= -O-1
  MCFLAGS-solver_type_bug		= --halt-at-warn
+# The following two test cases check for bugs that can only occur in the
+# presence of automatic solver type intialisation.
+MCFLAGS-solver_type_bug_2       = --solver-type-auto-init
+MCFLAGS-solver_type_mutable_bug = --solver-type-auto-init
  MCFLAGS-solv			= --halt-at-warn
  MCFLAGS-spurious_purity_warning	= --halt-at-warn
  MCFLAGS-stack_opt_simplify	= --optimize-saved-vars

--------------------------------------------------------------------------
mercury-reviews mailing list
Post messages to:       mercury-reviews at csse.unimelb.edu.au
Administrative Queries: owner-mercury-reviews at csse.unimelb.edu.au
Subscriptions:          mercury-reviews-request at csse.unimelb.edu.au
--------------------------------------------------------------------------



More information about the reviews mailing list