[m-rev.] for review: arg_vectors (part 1)

Julien Fischer juliensf at csse.unimelb.edu.au
Mon Dec 18 16:37:23 AEDT 2006


For review by Mark or Zoltan.

Estimated hours taken: 14
Branches: main

Add a new data structure, called an arg_vector, to the compiler that is
intended to encapsulate the argument passing conventions that we use.
(Primarily those described in the comments at the head of polymorphism.m).
The intention is to use this new data structure everywhere we currently use
lists to represent procedure and call site argument information.

This change adds the new data structure plus supporting utility predicates.
It also begins the task of moving the code in the compiler over to the new
data structure.  Specifically, this diff change the headvars field in the
clauses_info structure into an arg_vector.

The spots marked XXX ARGVEC will need to be further modified once the
proc_info structure has been modified to use arg_vectors.

compiler/hlds_args.m:
 	New module.  This module defines the arg_vector structure that will
 	eventually be used to represent procedure and call site argument
 	information throughout the compiler.  It also defines some utility
 	procedures that operate on that data structure.

compiler/hlds.m:
 	Include the new module in the HLDS package.

compiler/hlds_clauses.m:
 	Modify the clauses_info structure to represent clause arguments as
 	arg_vectors rather than lists.

 	Adapt the predicates that initialise the clauses_info structure so
 	that they correctly handle the arg_vector structure's representation
 	of function return values.

compiler/polymorphism.m:
 	Use the arg_vector data structure when introducing type_infos and
 	typeclass_info arguments.

 	Note: the new representation of procedure arguments should allow this
 	module to be simplified but that will be done as a separate change.

compiler/add_class.m:
compiler/add_clause.m:
compiler/add_pragma.m:
compiler/add_pred.m:
compiler/add_special_pred.m:
compiler/clause_to_proc.m:
compiler/build_mode_constraints.m:
compiler/hhf.m:
compiler/higher_order.m:
compiler/hlds_pred.m:
compiler/hlds_out.m:
compiler/intermod.m:
compiler/mode_constraints.m:
compiler/modes.m:
compiler/post_typecheck.m:
compiler/prop_mode_constraints.m:
compiler/typecheck.m:
compiler/unify_proc.m:
 	Conform to the above changes.

Julien.

Index: compiler/add_class.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/add_class.m,v
retrieving revision 1.24
diff -u -r1.24 add_class.m
--- compiler/add_class.m	1 Dec 2006 15:03:48 -0000	1.24
+++ compiler/add_class.m	13 Dec 2006 06:55:45 -0000
@@ -50,6 +50,7 @@
  :- implementation.

  :- import_module check_hlds.clause_to_proc.
+:- import_module hlds.hlds_args.
  :- import_module hlds.hlds_data.
  :- import_module hlds.hlds_goal.
  :- import_module hlds.hlds_rtti.
@@ -535,17 +536,18 @@
          IntroducedClause = clause([], IntroducedGoal, impl_lang_mercury,
              Context),

-        map.from_corresponding_lists(HeadVars, ArgTypes, VarTypes),
          map.init(TVarNameMap),
+        map.from_corresponding_lists(HeadVars, ArgTypes, VarTypes),
+        HeadVarVec = arg_vector_init(PredOrFunc, HeadVars),
+        set_clause_list([IntroducedClause], ClausesRep),
          rtti_varmaps_init(RttiVarMaps),
          HasForeignClauses = no,
-        set_clause_list([IntroducedClause], ClausesRep),
          ClausesInfo = clauses_info(VarSet, VarTypes, TVarNameMap, VarTypes,
-            HeadVars, ClausesRep, RttiVarMaps, HasForeignClauses)
+            HeadVarVec, ClausesRep, RttiVarMaps, HasForeignClauses)
      ;
          % Handle the arbitrary clauses syntax.
          InstanceProcDefn = instance_proc_def_clauses(InstanceClauses),
-        clauses_info_init(PredArity, ClausesInfo0),
+        clauses_info_init(PredOrFunc, PredArity, ClausesInfo0),
          list.foldl4(
              produce_instance_method_clause(PredOrFunc, Context, Status),
              InstanceClauses, !ModuleInfo, !QualInfo,
Index: compiler/add_clause.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/add_clause.m,v
retrieving revision 1.39
diff -u -r1.39 add_clause.m
--- compiler/add_clause.m	1 Dec 2006 15:03:48 -0000	1.39
+++ compiler/add_clause.m	13 Dec 2006 06:53:23 -0000
@@ -58,6 +58,7 @@
  :- import_module check_hlds.clause_to_proc.
  :- import_module check_hlds.mode_errors.
  :- import_module hlds.goal_util.
+:- import_module hlds.hlds_args.
  :- import_module hlds.hlds_data.
  :- import_module hlds.hlds_error_util.
  :- import_module hlds.hlds_out.
@@ -537,17 +538,18 @@
              HasForeignClauses)
      ).

-:- pred add_clause_transform(prog_substitution::in, list(prog_var)::in,
+:- pred add_clause_transform(prog_substitution::in, arg_vector(prog_var)::in,
      list(prog_term)::in, goal::in, prog_context::in, pred_or_func::in,
      arity::in, goal_type::in, hlds_goal::out,
      prog_varset::in, prog_varset::out, list(quant_warning)::out,
      module_info::in, module_info::out, qual_info::in, qual_info::out,
      list(error_spec)::in, list(error_spec)::out) is det.

-add_clause_transform(Subst, HeadVars, Args0, ParseBody, Context, PredOrFunc,
+add_clause_transform(Subst, HeadVarVec, Args0, ParseBody, Context, PredOrFunc,
          Arity, GoalType, Goal, !VarSet, Warnings, !ModuleInfo,
          !QualInfo, !Specs) :-
      some [!SInfo] (
+        HeadVars = arg_vector_to_list(HeadVarVec),
          prepare_for_head(!:SInfo),
          term.apply_substitution_to_list(Args0, Subst, Args1),
          substitute_state_var_mappings(Args1, Args, !VarSet, !SInfo, !Specs),
Index: compiler/add_pragma.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/add_pragma.m,v
retrieving revision 1.54
diff -u -r1.54 add_pragma.m
--- compiler/add_pragma.m	1 Dec 2006 15:03:49 -0000	1.54
+++ compiler/add_pragma.m	15 Dec 2006 03:57:30 -0000
@@ -129,6 +129,7 @@
  :- import_module backend_libs.foreign.
  :- import_module backend_libs.rtti.
  :- import_module check_hlds.mode_util.
+:- import_module hlds.hlds_args.
  :- import_module hlds.code_model.
  :- import_module hlds.hlds_data.
  :- import_module hlds.hlds_goal.
@@ -595,7 +596,7 @@
              PredOrFunc, SymName, Arity, [PredId])
      ->
          module_info_get_unused_arg_info(!.ModuleInfo, UnusedArgInfo0),
-        % convert the mode number to a proc_id
+        % Convert the mode number to a proc_id.
          proc_id_to_int(ProcId, ModeNum),
          map.set(UnusedArgInfo0, proc(PredId, ProcId), UnusedArgs,
              UnusedArgInfo),
@@ -790,11 +791,13 @@
                  SymName, Args, GoalInfo, Goal),
              Clause = clause(ProcIds, Goal, impl_lang_mercury, Context),
              map.init(TVarNameMap),
+            ArgsVec = arg_vector_init(PredOrFunc, Args),
+            set_clause_list([Clause], ClausesRep),
              rtti_varmaps_init(RttiVarMaps),
              HasForeignClauses = no,
-            set_clause_list([Clause], ClausesRep),
              Clauses = clauses_info(ArgVarSet, VarTypes0, TVarNameMap,
-                VarTypes0, Args, ClausesRep, RttiVarMaps, HasForeignClauses),
+                VarTypes0, ArgsVec, ClausesRep, RttiVarMaps,
+                HasForeignClauses),
              pred_info_get_markers(PredInfo0, Markers0),
              add_marker(marker_calls_are_fully_qualified, Markers0, Markers),
              map.init(Proofs),
@@ -2475,7 +2478,7 @@
          !ModuleInfo, !Specs) :-

      !.ClausesInfo = clauses_info(VarSet0, ExplicitVarTypes, TVarNameMap,
-        InferredVarTypes, HeadVars, ClauseRep, RttiVarMaps,
+        InferredVarTypes, HeadVarVec, ClauseRep, RttiVarMaps,
          _HasForeignClauses),
      get_clause_list(ClauseRep, ClauseList),

@@ -2574,6 +2577,9 @@
          ),
          % Put the purity in the goal_info in case this foreign code is inlined.
          goal_info_set_purity(Purity, GoalInfo1, GoalInfo),
+        % XXX ARGVEC - the foreign_args field in the hlds_goal_expr type
+        %     should also be a an arg_vector rather than a list.
+        HeadVars = arg_vector_to_list(HeadVarVec),
          make_foreign_args(HeadVars, ArgInfo, OrigArgTypes, ForeignArgs),
          % Perform some renaming in any user annotated sharing information.
          maybe_rename_user_annotated_sharing_information(Globals,
@@ -2606,7 +2612,7 @@
          HasForeignClauses = yes,
          set_clause_list(NewClauseList, NewClauseRep),
          !:ClausesInfo = clauses_info(VarSet, ExplicitVarTypes, TVarNameMap,
-            InferredVarTypes, HeadVars, NewClauseRep, RttiVarMaps,
+            InferredVarTypes, HeadVarVec, NewClauseRep, RttiVarMaps,
              HasForeignClauses)
      ).

Index: compiler/add_pred.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/add_pred.m,v
retrieving revision 1.26
diff -u -r1.26 add_pred.m
--- compiler/add_pred.m	1 Dec 2006 15:03:49 -0000	1.26
+++ compiler/add_pred.m	14 Dec 2006 07:03:51 -0000
@@ -73,6 +73,7 @@

  :- implementation.

+:- import_module hlds.hlds_args.
  :- import_module hlds.hlds_data.
  :- import_module hlds.hlds_goal.
  :- import_module hlds.hlds_pred.
@@ -173,7 +174,7 @@
      ;
          PredName = qualified(MNameOfPred, PName),
          module_info_get_predicate_table(!.ModuleInfo, PredTable0),
-        clauses_info_init(Arity, ClausesInfo),
+        clauses_info_init(PredOrFunc, Arity, ClausesInfo),
          map.init(Proofs),
          map.init(ConstraintMap),
          purity_to_markers(Purity, PurityMarkers),
@@ -229,10 +230,13 @@
      pred_info_context(!.PredInfo, Context),
      pred_info_clauses_info(!.PredInfo, ClausesInfo0),
      clauses_info_get_varset(ClausesInfo0, VarSet0),
-    clauses_info_get_headvars(ClausesInfo0, HeadVars),
+    clauses_info_get_headvars(ClausesInfo0, HeadVarVec),
+    % XXX ARGVEC - clean this up after the pred_info is converted to
+    %     use the arg_vector structure.
+    clauses_info_get_headvar_list(ClausesInfo0, HeadVars),

      goal_info_init(Context, GoalInfo0),
-    set.list_to_set(HeadVars, NonLocals),
+    NonLocals = arg_vector_to_set(HeadVarVec),
      goal_info_set_nonlocals(NonLocals, GoalInfo0, GoalInfo),
      (
          Module = mercury_private_builtin_module,
@@ -313,7 +317,7 @@
      HasForeignClauses = no,
      set_clause_list([Clause], ClausesRep),
      ClausesInfo = clauses_info(VarSet, VarTypes, TVarNameMap, VarTypes,
-        HeadVars, ClausesRep, RttiVarMaps, HasForeignClauses),
+        HeadVarVec, ClausesRep, RttiVarMaps, HasForeignClauses),
      pred_info_set_clauses_info(ClausesInfo, !PredInfo),

      % It's pointless but harmless to inline these clauses. The main purpose
@@ -436,7 +440,7 @@

  preds_add_implicit(ModuleInfo, ModuleName, PredName, Arity, Status, Context,
          Origin, PredOrFunc, PredId, !PredicateTable) :-
-    clauses_info_init(Arity, ClausesInfo),
+    clauses_info_init(PredOrFunc, Arity, ClausesInfo),
      preds_add_implicit_2(ClausesInfo, ModuleInfo, ModuleName, PredName,
          Arity, Status, Context, Origin, PredOrFunc, PredId, !PredicateTable).

Index: compiler/add_special_pred.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/add_special_pred.m,v
retrieving revision 1.17
diff -u -r1.17 add_special_pred.m
--- compiler/add_special_pred.m	1 Oct 2006 04:57:28 -0000	1.17
+++ compiler/add_special_pred.m	13 Dec 2006 06:57:47 -0000
@@ -347,15 +347,23 @@
      module_info_get_name(!.ModuleInfo, ModuleName),
      special_pred_interface(SpecialPredId, Type, ArgTypes, ArgModes, Det),
      Name = special_pred_name(SpecialPredId, TypeCtor),
-    ( SpecialPredId = spec_pred_init ->
+    (
+        SpecialPredId = spec_pred_init,
          TypeCtor = type_ctor(TypeSymName, _TypeArity),
          sym_name_get_module_name(TypeSymName, ModuleName, TypeModuleName),
          PredName = qualified(TypeModuleName, Name)
      ;
+        ( SpecialPredId = spec_pred_unify
+        ; SpecialPredId = spec_pred_index
+        ; SpecialPredId = spec_pred_compare
+        ),
          PredName = unqualified(Name)
      ),
      Arity = get_special_pred_id_arity(SpecialPredId),
-    clauses_info_init(Arity, ClausesInfo0),
+    % XXX we probably shouldn't hardcode this as predicate but since
+    % all current special_preds are predicates at the moment it doesn't
+    % matter.
+    clauses_info_init(predicate, Arity, ClausesInfo0),
      Origin = origin_special_pred(SpecialPredId - TypeCtor),
      adjust_special_pred_status(SpecialPredId, Status0, Status),
      map.init(Proofs),
Index: compiler/build_mode_constraints.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/build_mode_constraints.m,v
retrieving revision 1.21
diff -u -r1.21 build_mode_constraints.m
--- compiler/build_mode_constraints.m	27 Sep 2006 06:16:46 -0000	1.21
+++ compiler/build_mode_constraints.m	12 Dec 2006 07:33:28 -0000
@@ -197,6 +197,7 @@

  :- import_module check_hlds.inst_match.
  :- import_module check_hlds.mode_util.
+:- import_module hlds.hlds_args.
  :- import_module hlds.hlds_clauses.
  :- import_module libs.
  :- import_module libs.compiler_util.
@@ -263,9 +264,9 @@
  add_mc_vars_for_pred_head(ModuleInfo, PredId, !VarInfo) :-
      module_info_pred_info(ModuleInfo, PredId, PredInfo),
      pred_info_clauses_info(PredInfo, ClausesInfo),
-    clauses_info_get_headvars(ClausesInfo, Headvars),
+    clauses_info_get_headvar_list(ClausesInfo, HeadVars),
      clauses_info_get_varset(ClausesInfo, ProgVarset),
-    list.foldl(add_mc_var_for_pred_head(ProgVarset, PredId), Headvars,
+    list.foldl(add_mc_var_for_pred_head(ProgVarset, PredId), HeadVars,
          !VarInfo).

      % add_mc_var_for_pred_head(ProgVarset, PredId, ProgVar, !VarInfo)
@@ -363,7 +364,7 @@
          % annotations.
          MainGoal = disj(Goals),
          HeadGoalPath = [],
-        Nonlocals = set.list_to_set(HeadVars),
+        Nonlocals = arg_vector_to_set(HeadVars),
          add_goal_expr_constraints(ModuleInfo, ProgVarset, PredId, MainGoal,
              Context, HeadGoalPath, Nonlocals, !VarInfo, !Constraints)
      ).
@@ -439,7 +440,7 @@
      ( pred_info_infer_modes(CalleePredInfo) ->
          % No modes declared so just constrain the hearvars
          pred_info_clauses_info(CalleePredInfo, CalleeClausesInfo),
-        clauses_info_get_headvars(CalleeClausesInfo, CalleeHeadVars),
+        clauses_info_get_headvar_list(CalleeClausesInfo, CalleeHeadVars),
          add_mode_infer_callee(CalleePredId, !Constraints),
          add_call_headvar_constraints(ProgVarset, Context, GoalPath,
              CallerPredId, Args, CalleePredId, CalleeHeadVars,
Index: compiler/clause_to_proc.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/clause_to_proc.m,v
retrieving revision 1.74
diff -u -r1.74 clause_to_proc.m
--- compiler/clause_to_proc.m	7 Dec 2006 15:31:12 -0000	1.74
+++ compiler/clause_to_proc.m	12 Dec 2006 06:38:57 -0000
@@ -68,6 +68,7 @@

  :- import_module check_hlds.mode_util.
  :- import_module hlds.goal_util.
+:- import_module hlds.hlds_args.
  :- import_module hlds.hlds_goal.
  :- import_module hlds.hlds_rtti.
  :- import_module hlds.make_hlds.
@@ -192,7 +193,7 @@
      copy_clauses_to_procs_2(ProcIds, ClausesInfo, !Procs).

  copy_clauses_to_proc(ProcId, ClausesInfo, !Proc) :-
-    ClausesInfo = clauses_info(VarSet0, _, _, VarTypes, HeadVars,
+    ClausesInfo = clauses_info(VarSet0, _, _, VarTypes, HeadVarVec,
          ClausesRep, RttiInfo, _),
      get_clause_list(ClausesRep, Clauses),
      select_matching_clauses(Clauses, ProcId, MatchingClauses),
@@ -239,7 +240,7 @@
          %
          % The non-local vars are just the head variables.
          %
-        set.list_to_set(HeadVars, NonLocalVars),
+        NonLocalVars = arg_vector_to_set(HeadVarVec),
          goal_info_set_nonlocals(NonLocalVars, GoalInfo1, GoalInfo2),

          %
@@ -256,6 +257,9 @@

          Goal = disj(GoalList) - GoalInfo
      ),
+    % XXX ARGVEC - when the proc_info is converted to use arg_vectors
+    %     we should just pass the headvar vector in directly.
+    HeadVars = arg_vector_to_list(HeadVarVec),
      proc_info_set_body(VarSet, VarTypes, HeadVars, Goal, RttiInfo, !Proc).

  :- pred contains_nonpure_goal(list(hlds_goal)::in) is semidet.
Index: compiler/hhf.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/hhf.m,v
retrieving revision 1.27
diff -u -r1.27 hhf.m
--- compiler/hhf.m	1 Dec 2006 15:03:57 -0000	1.27
+++ compiler/hhf.m	13 Dec 2006 06:49:06 -0000
@@ -16,7 +16,6 @@
  % David Overton's PhD thesis.
  %
  %-----------------------------------------------------------------------------%
-%-----------------------------------------------------------------------------%

  :- module hlds.hhf.
  :- interface.
@@ -43,6 +42,7 @@
  :- implementation.

  :- import_module check_hlds.type_util.
+:- import_module hlds.hlds_args.
  :- import_module hlds.hlds_goal.
  :- import_module hlds.passes_aux.
  :- import_module libs.compiler_util.
@@ -67,7 +67,7 @@
          % AAA
          % PredInfo2 = PredInfo0
          pred_info_clauses_info(PredInfo0, ClausesInfo),
-        clauses_info_get_headvars(ClausesInfo, HeadVars),
+        clauses_info_get_headvar_list(ClausesInfo, HeadVars),
          clauses_info_get_varset(ClausesInfo, VarSet),
          some [!IG] (
              !:IG = PredInfo0 ^ inst_graph_info,
@@ -91,10 +91,10 @@
              !:IG = !.IG ^ implementation_inst_graph := ImplementationInstGraph,

              % AAA only for non-imported preds with no mode decls.
-            clauses_info_get_headvars(ClausesInfo, HeadVars),
+            clauses_info_get_headvar_list(ClausesInfo, HeadVars),
              clauses_info_get_varset(ClausesInfo, VarSet),
              !:IG = !.IG ^ interface_inst_graph := ImplementationInstGraph,
-            solutions.solutions(
+            solutions(
                  (pred(V::out) is nondet :-
                      list.member(V0, HeadVars),
                      inst_graph.reachable(ImplementationInstGraph,
@@ -143,7 +143,7 @@
      inst_graph.init(VarTypes0 ^ keys, InstGraph0),
      Info0 = hhf_info(InstGraph0, VarSet0, VarTypes0),

-    clauses_info_get_headvars(!.ClausesInfo, HeadVars),
+    clauses_info_get_headvar_list(!.ClausesInfo, HeadVars),
      clauses_info_clauses(Clauses0, !ClausesInfo),

      (
Index: compiler/higher_order.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/higher_order.m,v
retrieving revision 1.163
diff -u -r1.163 higher_order.m
--- compiler/higher_order.m	1 Dec 2006 15:03:57 -0000	1.163
+++ compiler/higher_order.m	14 Dec 2006 03:42:08 -0000
@@ -49,6 +49,7 @@
  :- import_module check_hlds.type_util.
  :- import_module check_hlds.unify_proc.
  :- import_module hlds.goal_util.
+:- import_module hlds.hlds_args.
  :- import_module hlds.hlds_clauses.
  :- import_module hlds.hlds_data.
  :- import_module hlds.hlds_goal.
@@ -2618,8 +2619,9 @@
      % This isn't looked at after here, and just clutters up HLDS dumps
      % if it's filled in.
      set_clause_list([], ClausesRep),
+    EmptyHeadVarVec = arg_vector_init(predicate, []),
      ClausesInfo = clauses_info(EmptyVarSet, EmptyVarTypes,
-        EmptyTVarNameMap, EmptyVarTypes, [], ClausesRep,
+        EmptyTVarNameMap, EmptyVarTypes, EmptyHeadVarVec, ClausesRep,
          EmptyRttiVarMaps, no),
      Origin = origin_transformed(Transform, OrigOrigin, CallerPredId),
      pred_info_init(PredModule, SymName, Arity, PredOrFunc, Context, Origin,
Index: compiler/hlds.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/hlds.m,v
retrieving revision 1.221
diff -u -r1.221 hlds.m
--- compiler/hlds.m	31 Jul 2006 08:31:39 -0000	1.221
+++ compiler/hlds.m	12 Dec 2006 06:17:07 -0000
@@ -20,6 +20,7 @@

  % The HLDS data structure itself
  :- include_module assertion.
+:- include_module hlds_args.
  :- include_module hlds_clauses.
  :- include_module hlds_data.
  :- include_module hlds_goal.
Index: compiler/hlds_args.m
===================================================================
RCS file: compiler/hlds_args.m
diff -N compiler/hlds_args.m
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ compiler/hlds_args.m	18 Dec 2006 05:31:52 -0000
@@ -0,0 +1,326 @@
+%-----------------------------------------------------------------------------%
+% vim: ft=mercury ts=4 sw=4 et
+%-----------------------------------------------------------------------------%
+% Copyright (C) 2006 The University of Melbourne.
+% This file may only be copied under the terms of the GNU General
+% Public License - see the file COPYING in the Mercury distribution.
+%-----------------------------------------------------------------------------%
+%
+% File: hlds_args.m.
+% Main authors: juliensf.
+%
+% This module defines the part of the HLDS that deals with procedure and call
+% site arguments.  (See comments at the head of polymorphism.m for further
+% details.)
+%
+%-----------------------------------------------------------------------------%
+
+:- module hlds.hlds_args.
+:- interface.
+ 
+:- import_module mdbcomp.prim_data.
+ 
+:- import_module list.
+:- import_module map.
+:- import_module maybe.
+:- import_module set.
+
+%-----------------------------------------------------------------------------%
+
+	% This type represents the arguments to a predicate symbol, or the
+	% arguments and result of a function symbol.  The arguments may be
+	% variables, types, modes, etc, depending on the context.
+	%
+	% Rather than keep all arguments in a single list, we retain
+	% information about the origin of each argument (such as whether
+	% it was introduced by polymorphism.m to hold a type_info).  This
+	% simplifies the processing in polymorphism.m, and also abstracts
+	% away the specific calling convention that we use.
+    %
+:- type arg_vector(T).
+ 
+%-----------------------------------------------------------------------------%
+ 
+    % Create a new arg_vector from the given list.
+    % If the first argument is `function' then the last element in the
+    % list is used to set the return value field of the arg_vector.
+    %
+:- func arg_vector_init(pred_or_func, list(T)) = arg_vector(T).
+
+%-----------------------------------------------------------------------------%
+% 
+% Access predicates for the arg_vector structure
+%
+
+:- func arg_vector_get_instance_type_infos(arg_vector(T)) = list(T).
+:- func arg_vector_get_instance_typeclass_infos(arg_vector(T)) = list(T).
+:- func arg_vector_get_univ_type_infos(arg_vector(T)) = list(T).
+:- func arg_vector_get_exist_type_infos(arg_vector(T)) = list(T).
+:- func arg_vector_get_univ_typeclass_infos(arg_vector(T)) = list(T).
+:- func arg_vector_get_exist_typeclass_infos(arg_vector(T)) = list(T).
+:- func arg_vector_get_user_args(arg_vector(T)) = list(T).
+:- func arg_vector_get_maybe_ret_value(arg_vector(T)) = maybe(T).
+
+:- pred arg_vector_set_instance_type_infos(list(T)::in,
+    arg_vector(T)::in, arg_vector(T)::out) is det.
+:- pred arg_vector_set_instance_typeclass_infos(list(T)::in,
+    arg_vector(T)::in, arg_vector(T)::out) is det.
+:- pred arg_vector_set_univ_type_infos(list(T)::in,
+    arg_vector(T)::in, arg_vector(T)::out) is det.
+:- pred arg_vector_set_exist_type_infos(list(T)::in,
+    arg_vector(T)::in, arg_vector(T)::out) is det.
+:- pred arg_vector_set_univ_typeclass_infos(list(T)::in,
+    arg_vector(T)::in, arg_vector(T)::out) is det.
+:- pred arg_vector_set_exist_typeclass_infos(list(T)::in,
+    arg_vector(T)::in, arg_vector(T)::out) is det.
+:- pred arg_vector_set_user_args(list(T)::in,
+    arg_vector(T)::in, arg_vector(T)::out) is det.
+:- pred arg_vector_set_maybe_ret_value(maybe(T)::in,
+    arg_vector(T)::in, arg_vector(T)::out) is det.
+
+%-----------------------------------------------------------------------------%
+%
+% Utility predicates that operate on arg_vectors
+%
+
+    % Return a list of the items in a arg_vector.  The order of the
+    % list corresponds to that required by the calling conventions.
+    % See comments at the head of polymorphism.m. for details.  If the
+    % arg_vector represents a function then the last element in the list
+    % will correspond to the function return value.
+    % 
+:- func arg_vector_to_list(arg_vector(T)) = list(T).
+ 
+    % Return the set of items in an arg_vector.
+    %
+:- func arg_vector_to_set(arg_vector(T)) = set(T).
+
+    % Apply a renaming to an arg_vector.
+    % Useful for renaming variables etc.
+    % 
+:- pred apply_renaming_to_arg_vector(map(T, T)::in,
+    arg_vector(T)::in, arg_vector(T)::out) is det.
+
+    % partition_arg_vector_by_origin(Vec, PolyArgs, NonPolyArgs):
+    %
+    % Partition the argument vector into two lists depending on whether
+    % something was introduced by the polymorphism transformation or not.
+    %
+:- pred partition_arg_vector_by_origin(arg_vector(T)::in, list(T)::out,
+    list(T)::out) is det.
+
+    % arg_vector_member(Vector, V):
+    % 
+    % Succeeds iff V is a member of the argument vector `Vector'.
+    % 
+:- pred arg_vector_member(arg_vector(T)::in, T::in) is semidet.
+
+    % Partition the given arg_vector into a list of arguments and
+    % a function return value.  Throws an exception if the arg_vector does
+    % not correspond to a function.
+    %
+:- pred arg_vector_to_func_args(arg_vector(T)::in, list(T)::out, T::out)
+    is det.
+
+%-----------------------------------------------------------------------------%
+%-----------------------------------------------------------------------------%
+
+:- implementation.
+
+:- import_module libs.compiler_util.
+:- import_module parse_tree.prog_util.
+:- import_module parse_tree.prog_type. 
+    % Require for apply_partial_map_to_list
+    % XXX that should really live in a different module.
+
+:- import_module string.
+
+%-----------------------------------------------------------------------------%
+
+    % The first six fields are set by the polymorphism pass.
+    %
+:- type arg_vector(T)
+    --->    arg_vector(
+                av_instance_type_infos :: list(T),
+                % Type_infos for the unconstrained type variables in an 
+                % instance declaration.  For procedures that are not
+                % class methods this will always be the empty list.
+ 
+                av_instance_typeclass_infos :: list(T),
+                % Typeclass_infos for the class constraints on an instance
+                % declaration, in the order in which they appear in the
+                % declaration.  For procedures that are not class methods
+                % this will always be the empty list.
+ 
+                av_univ_type_infos :: list(T),
+                % Type_infos for unconstrained universally quantified type
+                % variables, in the order in which they first appear in the
+                % argument types.
+ 
+                av_exist_type_infos :: list(T),
+                % Type_infos for unconstrained existentially quantified type
+                % variables, in the order that the type variables first
+                % appear in the argument types.
+ 
+                av_univ_typeclass_infos :: list(T),
+                % Typeclass_infos for universally quantified constraints
+                % in the order in which the constraints appear in the class
+                % context.
+ 
+                av_exist_typeclass_infos :: list(T),
+                % Typeclass_infos for existentially quantified constraints
+                % in the order in which the constraints appear in the class
+                % context.
+ 
+                av_user_args :: list(T),
+                % The original procedure arguments.
+                % XXX Plus at the moment any arguments that may be
+                % introduced by transformations performed by the compiler.
+                % Eventually these should be separated out.
+ 
+                av_maybe_ret_value :: maybe(T)
+                % For predicates this field is no; for functions it
+                % corresponds to the function's return value.
+            ).
+
+%-----------------------------------------------------------------------------%
+
+arg_vector_init(PredOrFunc, Args0) = ArgVec :-
+    (
+        PredOrFunc = predicate,
+        Args = Args0,
+        MaybeRetVal = no
+    ;
+        PredOrFunc = function,
+        pred_args_to_func_args(Args0, Args, RetVal),
+        MaybeRetVal = yes(RetVal)
+    ),
+    ArgVec = arg_vector([], [], [], [], [], [], Args, MaybeRetVal).
+
+%-----------------------------------------------------------------------------%
+
+arg_vector_get_instance_type_infos(V)      = V ^ av_instance_type_infos.
+arg_vector_get_instance_typeclass_infos(V) = V ^ av_instance_typeclass_infos.
+arg_vector_get_univ_type_infos(V)          = V ^ av_univ_type_infos.
+arg_vector_get_exist_type_infos(V)         = V ^ av_exist_type_infos.
+arg_vector_get_univ_typeclass_infos(V)     = V ^ av_univ_typeclass_infos.
+arg_vector_get_exist_typeclass_infos(V)    = V ^ av_exist_typeclass_infos.
+arg_vector_get_user_args(V)                = V ^ av_user_args.
+arg_vector_get_maybe_ret_value(V)          = V ^ av_maybe_ret_value.
+
+arg_vector_set_instance_type_infos(ITI, !V) :-
+    !:V = !.V ^ av_instance_type_infos := ITI.
+arg_vector_set_instance_typeclass_infos(ITCI, !V) :-
+    !:V = !.V ^ av_instance_typeclass_infos := ITCI.
+arg_vector_set_univ_type_infos(UTI, !V) :-
+    !:V = !.V ^ av_univ_type_infos := UTI.
+arg_vector_set_exist_type_infos(ETI, !V) :-
+    !:V = !.V ^ av_exist_type_infos := ETI.
+arg_vector_set_univ_typeclass_infos(UTCI, !V) :-
+    !:V = !.V ^ av_univ_typeclass_infos := UTCI.
+arg_vector_set_exist_typeclass_infos(ETCI, !V) :-
+    !:V = !.V ^ av_exist_typeclass_infos := ETCI.
+arg_vector_set_user_args(UA, !V) :-
+    !:V = !.V ^ av_user_args := UA.
+arg_vector_set_maybe_ret_value(RV, !V) :-
+    !:V = !.V ^ av_maybe_ret_value := RV.
+
+%-----------------------------------------------------------------------------%
+
+arg_vector_to_list(ArgVec) = List :-
+    ArgVec = arg_vector(InstanceTypeInfos, InstanceTypeClassInfos,
+        UnivTypeInfos, ExistTypeInfos, UnivTypeClassInfos,
+        ExistTypeClassInfos, OrigArgs, MaybeRetValue),
+    (
+        MaybeRetValue = yes(Value),
+        RetValue = [Value]
+    ;
+        MaybeRetValue = no,
+        RetValue = []
+    ),
+    list.condense([InstanceTypeInfos,
+           InstanceTypeClassInfos,
+           UnivTypeInfos,
+           ExistTypeInfos,
+           UnivTypeClassInfos,
+           ExistTypeClassInfos,
+           OrigArgs,
+           RetValue], List).
+
+arg_vector_to_set(ArgVec) = Set :-
+    List = arg_vector_to_list(ArgVec),
+    Set  = set.from_list(List).
+
+apply_renaming_to_arg_vector(Renaming, ArgVec0, ArgVec) :-
+    ArgVec0 = arg_vector(InstanceTypeInfos0, InstanceTypeClassInfos0,
+        UnivTypeInfos0, ExistTypeInfos0, UnivTypeClassInfos0,
+        ExistTypeClassInfos0, OrigArgs0, MaybeRetValue0),
+    apply_partial_map_to_list(Renaming, InstanceTypeInfos0, InstanceTypeInfos),
+    apply_partial_map_to_list(Renaming, InstanceTypeClassInfos0,
+        InstanceTypeClassInfos),
+    apply_partial_map_to_list(Renaming, UnivTypeInfos0, UnivTypeInfos),
+    apply_partial_map_to_list(Renaming, ExistTypeInfos0, ExistTypeInfos),
+    apply_partial_map_to_list(Renaming, UnivTypeClassInfos0,
+        UnivTypeClassInfos),
+    apply_partial_map_to_list(Renaming, ExistTypeClassInfos0,
+        ExistTypeClassInfos),
+    apply_partial_map_to_list(Renaming, OrigArgs0, OrigArgs),
+    (
+        MaybeRetValue0 = yes(Value0),
+        ( map.search(Renaming, Value0, Value) ->
+            MaybeRetValue = yes(Value)
+        ;
+            MaybeRetValue = yes(Value0)
+        )
+    ;
+        MaybeRetValue0 = no,
+        MaybeRetValue  = no
+    ),
+    ArgVec = arg_vector(InstanceTypeInfos, InstanceTypeClassInfos,
+        UnivTypeInfos, ExistTypeInfos, UnivTypeClassInfos,
+        ExistTypeClassInfos, OrigArgs, MaybeRetValue).
+
+partition_arg_vector_by_origin(ArgVec, PolyArgs, NonPolyArgs) :-
+    ArgVec = arg_vector(InstanceTypeInfos, InstanceTypeClassInfos,
+        UnivTypeInfos, ExistTypeInfos, UnivTypeClassInfos,
+        ExistTypeClassInfos, OrigArgs, MaybeRetValue),
+    list.condense([InstanceTypeInfos, InstanceTypeClassInfos,
+        UnivTypeInfos, ExistTypeInfos, UnivTypeClassInfos,
+        ExistTypeClassInfos], PolyArgs),
+    (
+        MaybeRetValue = yes(Value),
+        RetValue = [Value]
+    ;
+        MaybeRetValue = no,
+        RetValue = []
+    ),
+    NonPolyArgs = OrigArgs ++ RetValue.
+
+arg_vector_member(Vec, V) :-
+    List = arg_vector_to_list(Vec),
+    list.member(V, List).
+
+arg_vector_to_func_args(Vector, FuncArgs, FuncRetVal) :-
+    Vector = arg_vector(InstanceTypeInfos, InstanceTypeClassInfos,
+        UnivTypeInfos, ExistTypeInfos, UnivTypeClassInfos,
+        ExistTypeClassInfos, OrigArgs, MaybeRetValue),
+    FuncArgs = list.condense([InstanceTypeInfos, InstanceTypeClassInfos,
+        UnivTypeInfos, ExistTypeInfos, UnivTypeClassInfos,
+        ExistTypeClassInfos, OrigArgs]),
+    (
+        MaybeRetValue = yes(FuncRetVal)
+    ;
+        MaybeRetValue = no,
+        unexpected(this_file, "Call to arg_vector_to_func_args/3 " ++
+            "with predicate.")
+    ).
+
+%-----------------------------------------------------------------------------%
+
+:- func this_file = string.
+
+this_file = "hlds_args.m".
+
+%-----------------------------------------------------------------------------%
+:- end_module hlds.hlds_args.
+%-----------------------------------------------------------------------------%
Index: compiler/hlds_clauses.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/hlds_clauses.m,v
retrieving revision 1.6
diff -u -r1.6 hlds_clauses.m
--- compiler/hlds_clauses.m	1 Dec 2006 15:03:58 -0000	1.6
+++ compiler/hlds_clauses.m	12 Dec 2006 07:29:22 -0000
@@ -12,19 +12,22 @@
  % This module defines the part of the HLDS that deals with clauses.
  %
  %-----------------------------------------------------------------------------%
-%-----------------------------------------------------------------------------%

  :- module hlds.hlds_clauses.
  :- interface.

+:- import_module hlds.hlds_args.
  :- import_module hlds.hlds_goal.
  :- import_module hlds.hlds_pred.
  :- import_module hlds.hlds_rtti.
  :- import_module parse_tree.prog_data.
+:- import_module mdbcomp.prim_data.

  :- import_module bool.
  :- import_module list.

+%-----------------------------------------------------------------------------%
+
      % The clauses_info structure contains the clauses for a predicate
      % after conversion from the item_list by make_hlds.m.
      % Typechecking is performed on the clauses info, then the clauses
@@ -32,6 +35,7 @@
      % After mode analysis the clauses and the procedure goals are not
      % guaranteed to be the same, and the clauses are only kept so that
      % the optimized goal can be compared with the original in HLDS dumps.
+    %
  :- type clauses_info
      --->    clauses_info(
                  varset                  :: prog_varset,
@@ -51,7 +55,7 @@
                                          % Variable types inferred by
                                          % typecheck.m.

-                headvars                :: list(prog_var),
+                headvars                :: arg_vector(prog_var),
                                          % The head variables.

                  clauses_rep             :: clauses_rep,
@@ -64,7 +68,7 @@
                                          % Do we have foreign language clauses?
          ).

-:- pred clauses_info_init(int::in, clauses_info::out) is det.
+:- pred clauses_info_init(pred_or_func::in, int::in, clauses_info::out) is det.

  :- pred clauses_info_init_for_assertion(prog_vars::in, clauses_info::out)
      is det.
@@ -115,7 +119,15 @@
  :- pred clauses_info_get_rtti_varmaps(clauses_info::in, rtti_varmaps::out)
      is det.

-:- pred clauses_info_get_headvars(clauses_info::in, list(prog_var)::out) is det.
+:- pred clauses_info_get_headvars(clauses_info::in,
+    arg_vector(prog_var)::out) is det.
+
+    % Return the headvars as a list rather than as an arg_vector.
+    % New code should avoid using this and should instead be written to
+    % work with the arg_vector structure directly.
+    % 
+:- pred clauses_info_get_headvar_list(clauses_info::in, list(prog_var)::out)
+    is det.

  :- pred clauses_info_get_clauses_rep(clauses_info::in, clauses_rep::out) is det.

@@ -129,7 +141,7 @@
  :- pred clauses_info_clauses(list(clause)::out,
      clauses_info::in, clauses_info::out) is det.

-:- pred clauses_info_set_headvars(list(prog_var)::in,
+:- pred clauses_info_set_headvars(arg_vector(prog_var)::in,
      clauses_info::in, clauses_info::out) is det.

  :- pred clauses_info_set_clauses(list(clause)::in,
@@ -181,31 +193,37 @@

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

-clauses_info_init(Arity, ClausesInfo) :-
+clauses_info_init(PredOrFunc, Arity, ClausesInfo) :-
      map.init(VarTypes),
      map.init(TVarNameMap),
      varset.init(VarSet0),
      make_n_fresh_vars("HeadVar__", Arity, HeadVars, VarSet0, VarSet),
+    HeadVarVec = arg_vector_init(PredOrFunc, HeadVars),
      rtti_varmaps_init(RttiVarMaps),
      HasForeignClauses = no,
      set_clause_list([], ClausesRep),
      ClausesInfo = clauses_info(VarSet, VarTypes, TVarNameMap, VarTypes,
-        HeadVars, ClausesRep, RttiVarMaps, HasForeignClauses).
+        HeadVarVec, ClausesRep, RttiVarMaps, HasForeignClauses).

  clauses_info_init_for_assertion(HeadVars, ClausesInfo) :-
+    varset.init(VarSet),
      map.init(VarTypes),
      map.init(TVarNameMap),
-    varset.init(VarSet),
+    % Procedures introduced for assertions are always predicates, never
+    % functions.
+    HeadVarVec = arg_vector_init(predicate, HeadVars),
+    set_clause_list([], ClausesRep),
      rtti_varmaps_init(RttiVarMaps),
      HasForeignClauses = no,
-    set_clause_list([], ClausesRep),
      ClausesInfo = clauses_info(VarSet, VarTypes, TVarNameMap, VarTypes,
-        HeadVars, ClausesRep, RttiVarMaps, HasForeignClauses).
+        HeadVarVec, ClausesRep, RttiVarMaps, HasForeignClauses).

  clauses_info_get_varset(CI, CI ^ varset).
  clauses_info_get_explicit_vartypes(CI, CI ^ explicit_vartypes).
  clauses_info_get_vartypes(CI, CI ^ vartypes).
  clauses_info_get_headvars(CI, CI ^ headvars).
+clauses_info_get_headvar_list(CI, List) :-
+    List = arg_vector_to_list(CI ^ headvars).
  clauses_info_get_clauses_rep(CI, CI ^ clauses_rep).
  clauses_info_get_rtti_varmaps(CI, CI ^ clauses_rtti_varmaps).

Index: compiler/hlds_out.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/hlds_out.m,v
retrieving revision 1.414
diff -u -r1.414 hlds_out.m
--- compiler/hlds_out.m	14 Dec 2006 04:35:45 -0000	1.414
+++ compiler/hlds_out.m	14 Dec 2006 06:33:06 -0000
@@ -33,6 +33,7 @@
  :- module hlds.hlds_out.
  :- interface.

+:- import_module hlds.hlds_args.
  :- import_module hlds.hlds_clauses.
  :- import_module hlds.hlds_goal.
  :- import_module hlds.hlds_module.
@@ -133,7 +134,7 @@
      %   HeadVars, PredOrFunc, Clauses, MaybeVarTypes).
      %
  :- pred write_clauses(int::in, module_info::in, pred_id::in,
-    prog_varset::in, bool::in, list(prog_var)::in, pred_or_func::in,
+    prog_varset::in, bool::in, arg_vector(prog_var)::in, pred_or_func::in,
      list(clause)::in, maybe_vartypes::in, io::di, io::uo) is det.

      % write_clause(Indent, ModuleInfo, PredId, VarSet, AppendVarNums,
@@ -1051,7 +1052,8 @@
          TypeQual, !IO).

  write_clauses(Indent, ModuleInfo, PredId, VarSet, AppendVarNums,
-        HeadVars, PredOrFunc, Clauses0, TypeQual, !IO) :-
+        HeadVarVec, PredOrFunc, Clauses0, TypeQual, !IO) :-
+    HeadVars = arg_vector_to_list(HeadVarVec),
      write_clauses_2(Indent, ModuleInfo, PredId, VarSet,
          AppendVarNums, HeadVars, PredOrFunc, Clauses0, TypeQual, 1, !IO).

Index: compiler/hlds_pred.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/hlds_pred.m,v
retrieving revision 1.215
diff -u -r1.215 hlds_pred.m
--- compiler/hlds_pred.m	12 Dec 2006 05:35:44 -0000	1.215
+++ compiler/hlds_pred.m	16 Dec 2006 13:58:40 -0000
@@ -51,6 +51,7 @@
  :- import_module check_hlds.type_util.
  :- import_module hlds.goal_form.
  :- import_module hlds.goal_util.
+:- import_module hlds.hlds_args.
  :- import_module hlds.hlds_rtti.
  :- import_module libs.compiler_util.
  :- import_module libs.options.
@@ -1053,8 +1054,9 @@
      map.init(TVarNameMap),
      proc_info_get_rtti_varmaps(ProcInfo, RttiVarMaps),
      HasForeignClauses = no,
+    HeadVarVec = arg_vector_init(PredOrFunc, HeadVars),
      ClausesInfo = clauses_info(VarSet, VarTypes, TVarNameMap, VarTypes,
-        HeadVars, Clauses, RttiVarMaps, HasForeignClauses),
+        HeadVarVec, Clauses, RttiVarMaps, HasForeignClauses),

      map.init(Procs0),
      next_mode_id(Procs0, ProcId),
Index: compiler/intermod.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/intermod.m,v
retrieving revision 1.214
diff -u -r1.214 intermod.m
--- compiler/intermod.m	5 Dec 2006 03:50:52 -0000	1.214
+++ compiler/intermod.m	14 Dec 2006 03:46:32 -0000
@@ -1554,7 +1554,7 @@

      pred_info_clauses_info(PredInfo, ClausesInfo),
      clauses_info_get_varset(ClausesInfo, VarSet),
-    clauses_info_get_headvars(ClausesInfo, HeadVars),
+    clauses_info_get_headvar_list(ClausesInfo, HeadVars),
      clauses_info_clauses_only(ClausesInfo, Clauses),
      clauses_info_get_vartypes(ClausesInfo, VarTypes),

Index: compiler/mode_constraints.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/mode_constraints.m,v
retrieving revision 1.35
diff -u -r1.35 mode_constraints.m
--- compiler/mode_constraints.m	27 Sep 2006 06:16:54 -0000	1.35
+++ compiler/mode_constraints.m	13 Dec 2006 06:42:59 -0000
@@ -221,12 +221,12 @@
      some [!ClausesInfo, !Varset, !Vartypes, !Clauses, !Goals, !RttiVarMaps] (
          pred_info_clauses_info(PredInfo0, !:ClausesInfo),
          clauses_info_clauses_only(!.ClausesInfo, !:Clauses),
-        clauses_info_get_headvars(!.ClausesInfo, Headvars),
+        clauses_info_get_headvar_list(!.ClausesInfo, HeadVars),
          clauses_info_get_varset(!.ClausesInfo, !:Varset),
          clauses_info_get_vartypes(!.ClausesInfo, !:Vartypes),
          clauses_info_get_rtti_varmaps(!.ClausesInfo, !:RttiVarMaps),
          !:Goals = list.map(func(X) = clause_body(X), !.Clauses),
-        list.map_foldl3(correct_nonlocals_in_clause_body(Headvars), !Goals,
+        list.map_foldl3(correct_nonlocals_in_clause_body(HeadVars), !Goals,
              !Varset, !Vartypes, !RttiVarMaps),
          !:Clauses = list.map_corresponding(
              func(Clause, Goal) = 'clause_body :='(Clause, Goal),
@@ -369,7 +369,7 @@
          PredInfo0, PredInfo1),

      pred_info_clauses_info(PredInfo1, ClausesInfo0),
-    clauses_info_get_headvars(ClausesInfo0, HeadVars),
+    clauses_info_get_headvar_list(ClausesInfo0, HeadVars),
      InstGraph = PredInfo1 ^ inst_graph_info ^ implementation_inst_graph,
      inst_graph.foldl_reachable_from_list(
          ( pred(V::in, S0::in, S::out) is det :-
@@ -600,7 +600,7 @@
      InstGraph = PredInfo0 ^ inst_graph_info ^ implementation_inst_graph,
      pred_info_get_procedures(PredInfo0, ProcTable0),
      pred_info_clauses_info(PredInfo0, ClausesInfo0),
-    clauses_info_get_headvars(ClausesInfo0, HeadVars),
+    clauses_info_get_headvar_list(ClausesInfo0, HeadVars),

      HOModes0 = map.init,
      ( ( map.is_empty(ProcTable0) ; pred_info_infer_modes(PredInfo0) ) ->
@@ -650,12 +650,12 @@
      module_info_pred_info(!.ModuleInfo, PredId, PredInfo0),
      InstGraph = PredInfo0 ^ inst_graph_info ^ implementation_inst_graph,
      pred_info_clauses_info(PredInfo0, ClausesInfo),
-    clauses_info_get_headvars(ClausesInfo, HeadVars),
+    clauses_info_get_headvar_list(ClausesInfo, HeadVars),

      % DMO document this better
      % XXX Needed for analysing calls. May want to store the constraint
      % as an ROBDD instead.
-    solutions.solutions(arg_modes_map(HeadVars, InstGraph, ModeConstraint,
+    solutions(arg_modes_map(HeadVars, InstGraph, ModeConstraint,
          ModeConstraintInfo0), Modes),
      PredInfo = PredInfo0 ^ modes := Modes,
      % PredInfo = PredInfo0,
@@ -1022,7 +1022,7 @@
          VeryVerbose = no
      ),

-    clauses_info_get_headvars(!.ClausesInfo, HeadVars),
+    clauses_info_get_headvar_list(!.ClausesInfo, HeadVars),
      map.foldl2(input_output_constraints(HeadVars, InstGraph),
          InstGraph, !Constraint, !ConstraintInfo),

@@ -1256,7 +1256,7 @@
          % XXX we currently assume that all recursive calls are to the
          % same mode of the predicate.
          pred_info_clauses_info(PredInfo, ClausesInfo),
-        clauses_info_get_headvars(ClausesInfo, HeadVars),
+        clauses_info_get_headvar_list(ClausesInfo, HeadVars),
          call_constraints(GoalPath, PredId, HeadVars, Args,
              !Constraint, !GCInfo)
      ;
@@ -1283,8 +1283,8 @@
              ArgModes = PredInfo ^ modes,
              PredInstGraph = PredInfo ^ inst_graph_info ^ interface_inst_graph,
              pred_info_clauses_info(PredInfo, PredClausesInfo),
-            clauses_info_get_headvars(PredClausesInfo, PredHeadVars),
-            solutions.solutions((pred((V - W)::out) is nondet :-
+            clauses_info_get_headvar_list(PredClausesInfo, PredHeadVars),
+            solutions((pred((V - W)::out) is nondet :-
                  inst_graph.corresponding_nodes_from_lists(
                      PredInstGraph, InstGraph, PredHeadVars, Args, V, W)
                  ), CorrespondingNodes),
Index: compiler/modes.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/modes.m,v
retrieving revision 1.351
diff -u -r1.351 modes.m
--- compiler/modes.m	5 Dec 2006 03:50:55 -0000	1.351
+++ compiler/modes.m	13 Dec 2006 06:43:43 -0000
@@ -2603,7 +2603,7 @@
      mode_info_get_predid(!.ModeInfo, PredId),
      module_info_pred_info(ModuleInfo, PredId, PredInfo),
      pred_info_clauses_info(PredInfo, ClausesInfo),
-    clauses_info_get_headvars(ClausesInfo, HeadVars),
+    clauses_info_get_headvar_list(ClausesInfo, HeadVars),
      filter_headvar_unification_goals(HeadVars, DelayedGoals0,
          HeadVarUnificationGoals, NonHeadVarUnificationGoals0),
      modecheck_delayed_solver_goals(plain_conj, Goals,
Index: compiler/polymorphism.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/polymorphism.m,v
retrieving revision 1.310
diff -u -r1.310 polymorphism.m
--- compiler/polymorphism.m	7 Dec 2006 15:31:12 -0000	1.310
+++ compiler/polymorphism.m	15 Dec 2006 03:51:58 -0000
@@ -381,6 +381,7 @@
  :- import_module check_hlds.mode_util.
  :- import_module check_hlds.type_util.
  :- import_module hlds.goal_util.
+:- import_module hlds.hlds_args.
  :- import_module hlds.hlds_clauses.
  :- import_module hlds.hlds_code_util.
  :- import_module hlds.hlds_data.
@@ -462,19 +463,10 @@
      map.lookup(PredTable0, PredId, PredInfo0),
      pred_info_clauses_info(PredInfo0, ClausesInfo0),
      clauses_info_get_vartypes(ClausesInfo0, VarTypes0),
-    clauses_info_get_headvars(ClausesInfo0, HeadVars),
+    clauses_info_get_headvars(ClausesInfo0, HeadVarVec),

      pred_info_get_arg_types(PredInfo0, TypeVarSet, ExistQVars, ArgTypes0),
-    list.length(ArgTypes0, NumOldArgs),
-    list.length(HeadVars, NumNewArgs),
-    NumExtraArgs = NumNewArgs - NumOldArgs,
-    ( list.split_list(NumExtraArgs, HeadVars, ExtraHeadVars0, OldHeadVars0) ->
-        ExtraHeadVars = ExtraHeadVars0,
-        OldHeadVars = OldHeadVars0
-    ;
-        unexpected(this_file,
-            "fixup_pred_polymorphism: list.split_list failed")
-    ),
+    partition_arg_vector_by_origin(HeadVarVec, ExtraHeadVars, OldHeadVars),

      map.apply_to_list(ExtraHeadVars, VarTypes0, ExtraArgTypes),
      list.append(ExtraArgTypes, ArgTypes0, ArgTypes),
@@ -592,9 +584,10 @@
          VarTypes, HeadVars, ClausesRep, RttiVarMaps,
          !.ClausesInfo ^ have_foreign_clauses).

-:- pred polymorphism_process_clause(pred_info::in, list(prog_var)::in,
-    list(prog_var)::in, list(tvar)::in, list(prog_var)::in, list(prog_var)::in,
-    clause::in, clause::out, poly_info::in, poly_info::out) is det.
+:- pred polymorphism_process_clause(pred_info::in, arg_vector(prog_var)::in,
+    arg_vector(prog_var)::in, list(tvar)::in, list(prog_var)::in,
+    list(prog_var)::in, clause::in, clause::out,
+    poly_info::in, poly_info::out) is det.

  polymorphism_process_clause(PredInfo0, OldHeadVars, NewHeadVars,
          UnconstrainedTVars, ExtraTypeInfoHeadVars,
@@ -645,7 +638,10 @@
          % of the compiler (e.g. unused_args.m) depend on these fields being
          % valid even for imported procedures.

-        clauses_info_get_headvars(ClausesInfo, HeadVars),
+        % XXX ARGVEC - when the proc_info uses the arg_vector just
+        %     pass the headvar vector directly to the proc_info.
+        clauses_info_get_headvars(ClausesInfo, HeadVarVec),
+        HeadVars = arg_vector_to_list(HeadVarVec),
          clauses_info_get_rtti_varmaps(ClausesInfo, RttiVarMaps),
          clauses_info_get_varset(ClausesInfo, VarSet),
          clauses_info_get_vartypes(ClausesInfo, VarTypes),
@@ -668,8 +664,9 @@
      % existential/universal type_infos and type_class_infos
      % in a more consistent manner.
      %
-:- pred setup_headvars(pred_info::in, list(prog_var)::in,
-    list(prog_var)::out, list(mer_mode)::out, list(tvar)::out, list(tvar)::out,
+:- pred setup_headvars(pred_info::in, arg_vector(prog_var)::in,
+    arg_vector(prog_var)::out, list(mer_mode)::out,
+    list(tvar)::out, list(tvar)::out,
      list(prog_var)::out, list(prog_var)::out,
      poly_info::in, poly_info::out) is det.

@@ -684,13 +681,11 @@
              ExtraHeadTypeInfoVars, ExistHeadTypeClassInfoVars, !Info)
      ;
          pred_info_get_class_context(PredInfo, ClassContext),
-        ExtraHeadVars0 = [],
          ExtraArgModes0 = [],
          InstanceTVars = [],
          InstanceUnconstrainedTVars = [],
          InstanceUnconstrainedTypeInfoVars = [],
-        setup_headvars_2(PredInfo, ClassContext,
-            ExtraHeadVars0, ExtraArgModes0,
+        setup_headvars_2(PredInfo, ClassContext, ExtraArgModes0,
              InstanceTVars, InstanceUnconstrainedTVars,
              InstanceUnconstrainedTypeInfoVars, HeadVars0, HeadVars,
              ExtraArgModes, HeadTypeVars, UnconstrainedTVars,
@@ -703,12 +698,12 @@
      %
  :- pred setup_headvars_instance_method(pred_info::in,
      instance_method_constraints::in,
-    list(prog_var)::in, list(prog_var)::out,
+    arg_vector(prog_var)::in, arg_vector(prog_var)::out,
      list(mer_mode)::out, list(tvar)::out, list(tvar)::out, list(prog_var)::out,
      list(prog_var)::out, poly_info::in, poly_info::out) is det.

  setup_headvars_instance_method(PredInfo,
-        InstanceMethodConstraints, HeadVars0, HeadVars, ExtraArgModes,
+        InstanceMethodConstraints, !HeadVarVec, ExtraArgModes,
          HeadTypeVars, UnconstrainedTVars, ExtraHeadTypeInfoVars,
          ExistHeadTypeClassInfoVars, !Info) :-

@@ -727,25 +722,35 @@
      list.foldl(rtti_reuse_typeclass_info_var,
          InstanceHeadTypeClassInfoVars, RttiVarMaps0, RttiVarMaps),
      poly_info_set_rtti_varmaps(RttiVarMaps, !Info),
-    list.append(UnconstrainedInstanceTypeInfoVars,
-        InstanceHeadTypeClassInfoVars, ExtraHeadVars0),
      in_mode(InMode),
-    list.duplicate(list.length(ExtraHeadVars0), InMode, ExtraArgModes0),
+    list.duplicate(list.length(UnconstrainedInstanceTypeInfoVars),
+        InMode, UnconstrainedInstanceTypeInfoModes),
+    list.duplicate(list.length(InstanceHeadTypeClassInfoVars),
+        InMode, InstanceHeadTypeClassInfoModes),
+ 
+    ExtraArgModes0 = UnconstrainedInstanceTypeInfoModes ++
+        InstanceHeadTypeClassInfoModes,
+
+    arg_vector_set_instance_type_infos(UnconstrainedInstanceTypeInfoVars,
+        !HeadVarVec),
+    arg_vector_set_instance_typeclass_infos(InstanceHeadTypeClassInfoVars,
+        !HeadVarVec),
+
      setup_headvars_2(PredInfo, ClassContext,
-        ExtraHeadVars0, ExtraArgModes0, InstanceTVars,
+        ExtraArgModes0, InstanceTVars,
          UnconstrainedInstanceTVars, UnconstrainedInstanceTypeInfoVars,
-        HeadVars0, HeadVars, ExtraArgModes, HeadTypeVars,
+        !HeadVarVec, ExtraArgModes, HeadTypeVars,
          UnconstrainedTVars, ExtraHeadTypeInfoVars,
          ExistHeadTypeClassInfoVars, !Info).

  :- pred setup_headvars_2(pred_info::in, prog_constraints::in,
-    list(prog_var)::in, list(mer_mode)::in, list(tvar)::in, list(tvar)::in,
-    list(prog_var)::in, list(prog_var)::in, list(prog_var)::out,
+    list(mer_mode)::in, list(tvar)::in, list(tvar)::in,
+    list(prog_var)::in, arg_vector(prog_var)::in, arg_vector(prog_var)::out,
      list(mer_mode)::out, list(tvar)::out, list(tvar)::out,
      list(prog_var)::out, list(prog_var)::out,
      poly_info::in, poly_info::out) is det.

-setup_headvars_2(PredInfo, ClassContext, ExtraHeadVars0,
+setup_headvars_2(PredInfo, ClassContext,
          ExtraArgModes0, InstanceTVars, UnconstrainedInstanceTVars,
          UnconstrainedInstanceTypeInfoVars, HeadVars0,
          HeadVars, ExtraArgModes, HeadTypeVars, AllUnconstrainedTVars,
@@ -796,9 +801,6 @@
      make_typeclass_info_head_vars(do_record_type_info_locns, UnivConstraints,
          UnivHeadTypeClassInfoVars, !Info),

-    list.append(UnivHeadTypeClassInfoVars, ExistHeadTypeClassInfoVars,
-        ExtraHeadTypeClassInfoVars),
-
      type_vars_list(ArgTypes, HeadTypeVars),
      list.delete_elems(HeadTypeVars, UnivConstrainedTVars,
          UnconstrainedTVars0),
@@ -835,10 +837,16 @@
          ++ ExtraHeadTypeInfoVars,
      list.condense([UnconstrainedInstanceTVars, UnconstrainedUnivTVars,
          UnconstrainedExistTVars], AllUnconstrainedTVars),
-
-    HeadVars = ExtraHeadVars0 ++ ExtraHeadTypeInfoVars
-        ++ ExtraHeadTypeClassInfoVars ++ HeadVars0,
-
+ 
+    arg_vector_set_univ_type_infos(UnivHeadTypeInfoVars,
+        HeadVars0, HeadVars1),
+    arg_vector_set_exist_type_infos(ExistHeadTypeInfoVars,
+        HeadVars1, HeadVars2),
+    arg_vector_set_univ_typeclass_infos(UnivHeadTypeClassInfoVars,
+        HeadVars2, HeadVars3),
+    arg_vector_set_exist_typeclass_infos(ExistHeadTypeClassInfoVars,
+        HeadVars3, HeadVars),
+
      % Figure out the modes of the introduced type_info and typeclass_info
      % arguments.

@@ -892,11 +900,11 @@
      % existential/universal type_infos and type_class_infos
      % in a more consistent manner.
      %
-:- pred produce_existq_tvars(pred_info::in, list(prog_var)::in,
+:- pred produce_existq_tvars(pred_info::in, arg_vector(prog_var)::in,
      list(tvar)::in, list(prog_var)::in, list(prog_var)::in,
      hlds_goal::in, hlds_goal::out, poly_info::in, poly_info::out) is det.

-produce_existq_tvars(PredInfo, HeadVars0, UnconstrainedTVars,
+produce_existq_tvars(PredInfo, HeadVarVec, UnconstrainedTVars,
          TypeInfoHeadVars, ExistTypeClassInfoHeadVars, Goal0, Goal, !Info) :-
      poly_info_get_var_types(!.Info, VarTypes0),
      poly_info_get_constraint_map(!.Info, ConstraintMap),
@@ -930,7 +938,8 @@
          % This can happen for compiler generated procedures.
          map.init(PredToActualTypeSubst)
      ;
-        map.apply_to_list(HeadVars0, VarTypes0, ActualArgTypes),
+        HeadVars = arg_vector_to_list(HeadVarVec),
+        map.apply_to_list(HeadVars, VarTypes0, ActualArgTypes),
          type_list_subsumes(ArgTypes, ActualArgTypes, ArgTypeSubst)
      ->
          PredToActualTypeSubst = ArgTypeSubst
@@ -1903,7 +1912,7 @@
      % type(class)-info. The nonlocals for those goals are adjusted by
      % the code which creates/alters them.
      %
-:- pred fixup_quantification(list(prog_var)::in,
+:- pred fixup_quantification(arg_vector(prog_var)::in,
      existq_tvars::in, hlds_goal::in, hlds_goal::out,
      poly_info::in, poly_info::out) is det.

@@ -1918,7 +1927,7 @@
          poly_info_get_varset(!.Info, VarSet0),
          poly_info_get_var_types(!.Info, VarTypes0),
          poly_info_get_rtti_varmaps(!.Info, RttiVarMaps0),
-        set.list_to_set(HeadVars, OutsideVars),
+        OutsideVars = arg_vector_to_set(HeadVars),
          implicitly_quantify_goal(OutsideVars, _Warnings, Goal0, Goal,
              VarSet0, VarSet, VarTypes0, VarTypes, RttiVarMaps0, RttiVarMaps),
          poly_info_set_varset_and_types(VarSet, VarTypes, !Info),
Index: compiler/post_typecheck.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/post_typecheck.m,v
retrieving revision 1.112
diff -u -r1.112 post_typecheck.m
--- compiler/post_typecheck.m	6 Nov 2006 07:55:12 -0000	1.112
+++ compiler/post_typecheck.m	13 Dec 2006 06:44:19 -0000
@@ -441,7 +441,7 @@
          true
      ;
          pred_info_clauses_info(!.PredInfo, ClausesInfo0),
-        clauses_info_get_headvars(ClausesInfo0, HeadVars),
+        clauses_info_get_headvar_list(ClausesInfo0, HeadVars),
          pred_info_get_arg_types(!.PredInfo, ArgTypes),
          map.from_corresponding_lists(HeadVars, ArgTypes, VarTypes),
          clauses_info_set_vartypes(VarTypes, ClausesInfo0, ClausesInfo),
Index: compiler/prop_mode_constraints.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/prop_mode_constraints.m,v
retrieving revision 1.14
diff -u -r1.14 prop_mode_constraints.m
--- compiler/prop_mode_constraints.m	27 Sep 2006 06:17:02 -0000	1.14
+++ compiler/prop_mode_constraints.m	13 Dec 2006 06:45:42 -0000
@@ -5,16 +5,16 @@
  % This file may only be copied under the terms of the GNU General
  % Public License - see the file COPYING in the Mercury distribution.
  %-----------------------------------------------------------------------------%
-
+%
  % File: prop_mode_constraints.m.
  % Main author: richardf.
-
+%
  % XXX This module essentially serves as interface between the
  % pre-existing mode_constraints module and the new
  % abstract_mode_constraints and build_mode_constraints modules.
  % Ultimately its contents should probably be moved into those
  % modules respectively.
-
+%
  %-----------------------------------------------------------------------------%

  :- module check_hlds.prop_mode_constraints.
@@ -77,6 +77,7 @@
  :- implementation.

  :- import_module check_hlds.goal_path.
+:- import_module hlds.hlds_args.
  :- import_module hlds.hlds_clauses.
  :- import_module hlds.hlds_error_util.
  :- import_module hlds.hlds_goal.
@@ -239,9 +240,9 @@
      clauses_info_clauses_only(ClausesInfo0, Clauses0),
      clauses_info_get_varset(ClausesInfo0, Varset0),
      clauses_info_get_vartypes(ClausesInfo0, Vartypes0),
-    clauses_info_get_headvars(ClausesInfo0, HeadVars),
+    clauses_info_get_headvars(ClausesInfo0, HeadVarVec),

-    SeenSoFar = set.from_list(HeadVars),
+    SeenSoFar = arg_vector_to_set(HeadVarVec),
      BodyGoals0 = list.map(func(X) = clause_body(X), Clauses0),
      list.map_foldl3(ensure_unique_arguments_in_goal, BodyGoals0, BodyGoals,
          SeenSoFar, _, Varset0, Varset, Vartypes0, Vartypes),
Index: compiler/typecheck.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/typecheck.m,v
retrieving revision 1.414
diff -u -r1.414 typecheck.m
--- compiler/typecheck.m	5 Dec 2006 03:51:00 -0000	1.414
+++ compiler/typecheck.m	14 Dec 2006 07:37:13 -0000
@@ -76,7 +76,6 @@
  %-----------------------------------------------------------------------------%

  :- module check_hlds.typecheck.
-
  :- interface.

  :- import_module hlds.
@@ -109,6 +108,7 @@
  :- import_module check_hlds.typecheck_info.
  :- import_module check_hlds.typeclasses.
  :- import_module hlds.goal_util.
+:- import_module hlds.hlds_args.
  :- import_module hlds.hlds_clauses.
  :- import_module hlds.hlds_data.
  :- import_module hlds.hlds_error_util.
@@ -139,6 +139,8 @@
  :- import_module set.
  :- import_module std_util.
  :- import_module string.
+:- import_module svmap.
+:- import_module svvarset.
  :- import_module term.
  :- import_module varset.

@@ -378,7 +380,7 @@
      some [!ClausesInfo, !Info, !HeadTypeParams] (
          pred_info_clauses_info(!.PredInfo, !:ClausesInfo),
          clauses_info_get_clauses_rep(!.ClausesInfo, ClausesRep0),
-        clauses_info_get_headvars(!.ClausesInfo, HeadVars),
+        clauses_info_get_headvar_list(!.ClausesInfo, HeadVars),
          clauses_info_get_varset(!.ClausesInfo, VarSet0),
          clauses_info_get_explicit_vartypes(!.ClausesInfo, ExplicitVarTypes0),
          pred_info_get_markers(!.PredInfo, Markers0),
@@ -415,7 +417,7 @@
              % There are no clauses for class methods. The clauses are generated
              % later on, in polymorphism.expand_class_method_bodies.
              ( check_marker(Markers0, marker_class_method) ->
-                % For the moment, we just insert the types of the head varss
+                % For the moment, we just insert the types of the head vars
                  % into the clauses_info.
                  map.from_corresponding_lists(HeadVars, ArgTypes0, VarTypes),
                  clauses_info_set_vartypes(VarTypes, !ClausesInfo),
@@ -880,8 +882,8 @@
          clause_list_is_empty(ClausesRep0) = yes,
          status_defined_in_this_module(ImportStatus) = yes
      ->
-        clauses_info_get_headvars(ClausesInfo0, HeadVars),
-        pred_args_to_func_args(HeadVars, FuncArgs, FuncRetVal),
+        clauses_info_get_headvars(ClausesInfo0, HeadVarVec),
+        arg_vector_to_func_args(HeadVarVec, FuncArgs, FuncRetVal),
          pred_info_context(!.PredInfo, Context),
          FuncModule = pred_info_module(!.PredInfo),
          FuncName = pred_info_name(!.PredInfo),
@@ -892,10 +894,10 @@
              rhs_functor(cons(FuncSymName, FuncArity), no, FuncArgs),
              Context, umc_explicit, [], Goal0),
          Goal0 = GoalExpr - GoalInfo0,
-        set.list_to_set(HeadVars, NonLocals),
+        NonLocals = arg_vector_to_set(HeadVarVec),
          goal_info_set_nonlocals(NonLocals, GoalInfo0, GoalInfo),
          Goal = GoalExpr - GoalInfo,
-        ProcIds = [], % the clause applies to all procedures.
+        ProcIds = [], % The clause applies to all procedures.
          Clause = clause(ProcIds, Goal, impl_lang_mercury, Context),
          clauses_info_set_clauses([Clause], ClausesInfo0, ClausesInfo),
          pred_info_update_goal_type(goal_type_clause_and_foreign, !PredInfo),
@@ -919,7 +921,7 @@
  maybe_improve_headvar_names(Globals, !PredInfo) :-
      pred_info_clauses_info(!.PredInfo, ClausesInfo0),
      clauses_info_clauses_only(ClausesInfo0, Clauses0),
-    clauses_info_get_headvars(ClausesInfo0, HeadVars0),
+    clauses_info_get_headvars(ClausesInfo0, HeadVarVec0),
      clauses_info_get_varset(ClausesInfo0, VarSet0),
      (
          % Don't do this when making a `.opt' file.
@@ -938,7 +940,7 @@

          Goal0 = _ - GoalInfo0,
          goal_to_conj_list(Goal0, Conj0),
-        improve_single_clause_headvars(Conj0, HeadVars0, [],
+        improve_single_clause_headvars(Conj0, HeadVarVec0, [],
              VarSet0, VarSet, map.init, Subst, [], RevConj),

          goal_info_get_nonlocals(GoalInfo0, NonLocals0),
@@ -946,8 +948,8 @@
          goal_info_set_nonlocals(NonLocals, GoalInfo0, GoalInfo),
          conj_list_to_goal(list.reverse(RevConj), GoalInfo, Goal),

-        apply_partial_map_to_list(Subst, HeadVars0, HeadVars),
-        clauses_info_set_headvars(HeadVars, ClausesInfo0, ClausesInfo1),
+        apply_renaming_to_arg_vector(Subst, HeadVarVec0, HeadVarVec),
+        clauses_info_set_headvars(HeadVarVec, ClausesInfo0, ClausesInfo1),

          SingleClause = clause(ApplicableProcs, Goal, Language, Context),
          clauses_info_set_clauses([SingleClause], ClausesInfo1, ClausesInfo2),
@@ -956,7 +958,7 @@
      ;
          % If a headvar is assigned to a variable with the same name
          % (or no name) in every clause, rename it to have that name.
-        list.foldl2(find_headvar_names_in_clause(VarSet0, HeadVars0),
+        list.foldl2(find_headvar_names_in_clause(VarSet0, HeadVarVec0),
              Clauses0, map.init, HeadVarNames, yes, _),
          map.foldl(maybe_update_headvar_name, HeadVarNames, VarSet0, VarSet),
          clauses_info_set_varset(VarSet, ClausesInfo0, ClausesInfo),
@@ -975,21 +977,22 @@
          VarSet = VarSet0
      ).

-:- pred improve_single_clause_headvars(list(hlds_goal)::in, list(prog_var)::in,
-    list(prog_var)::in, prog_varset::in, prog_varset::out,
+:- pred improve_single_clause_headvars(list(hlds_goal)::in,
+    arg_vector(prog_var)::in, list(prog_var)::in,
+    prog_varset::in, prog_varset::out,
      map(prog_var, prog_var)::in, map(prog_var, prog_var)::out,
      list(hlds_goal)::in, list(hlds_goal)::out) is det.

  improve_single_clause_headvars([], _, _, !VarSet, !Subst, !RevConj).
-improve_single_clause_headvars([Goal | Conj0], HeadVars, SeenVars0,
+improve_single_clause_headvars([Goal | Conj0], HeadVarVec, SeenVars0,
          !VarSet, !Subst, !RevConj) :-
-    ( goal_is_headvar_unification(HeadVars, Goal, HeadVar, OtherVar) ->
+    ( goal_is_headvar_unification(HeadVarVec, Goal, HeadVar, OtherVar) ->
          % If the headvar doesn't appear elsewhere the unification
          % can be removed.
          (
              % The headvars must be distinct variables, so check that this
              % variable doesn't already appear in the argument list.
-            \+ list.member(OtherVar, HeadVars),
+            \+ arg_vector_member(HeadVarVec, OtherVar),
              \+ list.member(OtherVar, SeenVars0),

              \+ ( some [OtherGoal] (
@@ -1002,14 +1005,14 @@
              ))
          ->
              SeenVars = [OtherVar | SeenVars0],
-            !:Subst = map.det_insert(!.Subst, HeadVar, OtherVar),
+            svmap.det_insert(HeadVar, OtherVar, !Subst),

              % If the variable wasn't named, use the `HeadVar__n' name.
              (
                  \+ varset.search_name(!.VarSet, OtherVar, _),
                  varset.search_name(!.VarSet, HeadVar, HeadVarName)
              ->
-                varset.name_var(!.VarSet, OtherVar, HeadVarName, !:VarSet)
+                svvarset.name_var(OtherVar, HeadVarName, !VarSet)
              ;
                  true
              )
@@ -1019,10 +1022,10 @@
              ( varset.search_name(!.VarSet, OtherVar, OtherVarName) ->
                  % The unification can't be eliminated,
                  % so just rename the head variable.
-                varset.name_var(!.VarSet, HeadVar, OtherVarName, !:VarSet)
+                svvarset.name_var(HeadVar, OtherVarName, !VarSet)
              ; varset.search_name(!.VarSet, HeadVar, HeadVarName) ->
                  % If the variable wasn't named, use the `HeadVar__n' name.
-                varset.name_var(!.VarSet, OtherVar, HeadVarName, !:VarSet)
+                svvarset.name_var(OtherVar, HeadVarName, !VarSet)
              ;
                  true
              )
@@ -1031,23 +1034,23 @@
          !:RevConj = [Goal | !.RevConj],
          SeenVars = SeenVars0
      ),
-    improve_single_clause_headvars(Conj0, HeadVars, SeenVars,
-        !VarSet, !Subst, !RevConj).
+    improve_single_clause_headvars(Conj0, HeadVarVec, SeenVars, !VarSet,
+        !Subst, !RevConj).

      % Head variables that have the same name in each clause
      % will have an entry of `yes(Name)' in the result map.
      %
  :- pred find_headvar_names_in_clause(prog_varset::in,
-    list(prog_var)::in, clause::in,
+    arg_vector(prog_var)::in, clause::in,
      map(prog_var, maybe(string))::in, map(prog_var, maybe(string))::out,
      bool::in, bool::out) is det.

-find_headvar_names_in_clause(VarSet, HeadVars, Clause, HeadVarMap0, HeadVarMap,
-        IsFirstClause, no) :-
+find_headvar_names_in_clause(VarSet, HeadVarVec, Clause,
+        HeadVarMap0, HeadVarMap, IsFirstClause, no) :-
      Goal = Clause ^ clause_body,
      goal_to_conj_list(Goal, Conj),
      ClauseHeadVarMap = list.foldl(
-        find_headvar_names_in_goal(VarSet, HeadVars), Conj, map.init),
+        find_headvar_names_in_goal(VarSet, HeadVarVec), Conj, map.init),
      (
          IsFirstClause = yes,
          HeadVarMap = ClauseHeadVarMap
@@ -1082,11 +1085,12 @@
              ), HeadVarMap1, HeadVarMap1)
      ).

-:- func find_headvar_names_in_goal(prog_varset, list(prog_var), hlds_goal,
+:- func find_headvar_names_in_goal(prog_varset, arg_vector(prog_var), hlds_goal,
      map(prog_var, maybe(string))) = map(prog_var, maybe(string)).

-find_headvar_names_in_goal(VarSet, HeadVars, Goal, HeadVarMap0) = HeadVarMap :-
-    ( goal_is_headvar_unification(HeadVars, Goal, HeadVar, OtherVar) ->
+find_headvar_names_in_goal(VarSet, HeadVarVec, Goal, HeadVarMap0)
+        = HeadVarMap :-
+    ( goal_is_headvar_unification(HeadVarVec, Goal, HeadVar, OtherVar) ->
          maybe_pred(varset.search_name(VarSet), OtherVar, MaybeOtherVarName),
          ( map.search(HeadVarMap0, HeadVar, MaybeHeadVarName) ->
              ( MaybeOtherVarName = MaybeHeadVarName ->
@@ -1101,15 +1105,15 @@
          HeadVarMap = HeadVarMap0
      ).

-:- pred goal_is_headvar_unification(list(prog_var)::in, hlds_goal::in,
+:- pred goal_is_headvar_unification(arg_vector(prog_var)::in, hlds_goal::in,
      prog_var::out, prog_var::out) is semidet.

-goal_is_headvar_unification(HeadVars, Goal, HeadVar, OtherVar) :-
+goal_is_headvar_unification(HeadVarVec, Goal, HeadVar, OtherVar) :-
      Goal = unify(LVar, rhs_var(RVar), _, _, _) - _,
-    ( list.member(LVar, HeadVars) ->
+    ( arg_vector_member(HeadVarVec, LVar) ->
          HeadVar = LVar,
          OtherVar = RVar
-    ; list.member(RVar, HeadVars) ->
+    ; arg_vector_member(HeadVarVec, RVar) ->
          HeadVar = RVar,
          OtherVar = LVar
      ;
Index: compiler/unify_proc.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/unify_proc.m,v
retrieving revision 1.179
diff -u -r1.179 unify_proc.m
--- compiler/unify_proc.m	1 Dec 2006 15:04:27 -0000	1.179
+++ compiler/unify_proc.m	14 Dec 2006 07:08:15 -0000
@@ -149,6 +149,7 @@
  :- import_module check_hlds.type_util.
  :- import_module check_hlds.unique_modes.
  :- import_module hlds.goal_util.
+:- import_module hlds.hlds_args.
  :- import_module hlds.hlds_out.
  :- import_module hlds.instmap.
  :- import_module hlds.make_hlds.
@@ -671,10 +672,11 @@
          info_extract(!.Info, VarSet, Types)
      ),
      map.init(TVarNameMap),
-    rtti_varmaps_init(RttiVarMaps),
+    ArgVec = arg_vector_init(predicate, Args),
      set_clause_list(Clauses, ClausesRep),
+    rtti_varmaps_init(RttiVarMaps),
      HasForeignClauses = yes,
-    ClauseInfo = clauses_info(VarSet, Types, TVarNameMap, Types, Args,
+    ClauseInfo = clauses_info(VarSet, Types, TVarNameMap, Types, ArgVec,
          ClausesRep, RttiVarMaps, HasForeignClauses).

  :- pred generate_initialise_clauses(mer_type::in,

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