[m-rev.] diff: oisu pragma checking

Zoltan Somogyi zs at unimelb.edu.au
Tue Oct 9 14:42:51 AEDT 2012


Implement semantic checks for oisu (order independent state update) pragmas.

compiler/hlds_pred.m:
	Record for each procedure whether it implements an operation
	on a oisu type, and if yes, what kind of operation.

compiler/hlds_module.m:
	Add to module_infos a data structure that lists the oisu pragmas
	in the module, and the procedures mentioned in them. These are intended
	to be used later during code generation.

compiler/add_pragma.m:
	Add such pragmas to the HLDS, after checking whatever properties
	can be checked during the creation of the HLDS.

compiler/oisu_check.m:
	A new module, whose job it is to check those aspects of oisu pragmas
	that can be checked only after other semantics are complete on the
	module.

compiler/check_hlds.m:
	Add the new module.

compiler/notes/compiler_design.html:
	Document the new module.

compiler/mercury_compile_front_end.m:
	Invoke the new module.

compiler/error_util.m:
	Add the new semantic check as a phase.

compiler/mercury_to_mercury.m:
	Fix typos in the code for writing out oisu pragmas.

compiler/prog_io_pragmas.m:
	Fix typos in the code for reading in oisu pragmas.

compiler/module_qual.m:
	Improve the error messages generated for any problems discovered during
	module qualification inside pragmas, by writing out what *kind* of
	pragma the problem was discovered in.

compiler/modules.m:
	Fix a bug: oisu pragmas *can* appear in module interfaces.

compiler/stratify.m:
	Give a predicate a better interface and a name.

compiler/hlds_goal.m:
	Remove a duplicate comment.

compiler/make_hlds_passes.m:
	Fix formatting.

tests/hard_coded/oisu_check_main.{m,exp}:
tests/hard_coded/oisu_check_db.m:
	A new multimodule test case, which uses oisu pragmas correctly.

tests/invalid/oisu_check_add_pragma_errors.{m,err_exp}:
	A new test case, which tests add_pragma.m's ability to diagnose
	the problems it is supposed to diagnose.

tests/invalid/oisu_check_semantic_errors.{m,err_exp}:
	A new test case, which tests oisu_check.m's ability to diagnose
	the problems it is supposed to diagnose.

tests/hard_coded/Mmakefile:
tests/invalid/Mmakefile:
	Enable the new test cases.

Zoltan.

cvs diff: Diffing .
cvs diff: Diffing analysis
cvs diff: Diffing bindist
cvs diff: Diffing boehm_gc
cvs diff: Diffing boehm_gc/Mac_files
cvs diff: Diffing boehm_gc/cord
cvs diff: Diffing boehm_gc/cord/private
cvs diff: Diffing boehm_gc/doc
cvs diff: Diffing boehm_gc/extra
cvs diff: Diffing boehm_gc/include
cvs diff: Diffing boehm_gc/include/extra
cvs diff: Diffing boehm_gc/include/private
cvs diff: Diffing boehm_gc/libatomic_ops
cvs diff: Diffing boehm_gc/libatomic_ops/doc
cvs diff: Diffing boehm_gc/libatomic_ops/pkgconfig
cvs diff: Diffing boehm_gc/libatomic_ops/src
cvs diff: Diffing boehm_gc/libatomic_ops/src/atomic_ops
cvs diff: Diffing boehm_gc/libatomic_ops/src/atomic_ops/sysdeps
cvs diff: Diffing boehm_gc/libatomic_ops/src/atomic_ops/sysdeps/armcc
cvs diff: Diffing boehm_gc/libatomic_ops/src/atomic_ops/sysdeps/gcc
cvs diff: Diffing boehm_gc/libatomic_ops/src/atomic_ops/sysdeps/hpc
cvs diff: Diffing boehm_gc/libatomic_ops/src/atomic_ops/sysdeps/ibmc
cvs diff: Diffing boehm_gc/libatomic_ops/src/atomic_ops/sysdeps/icc
cvs diff: Diffing boehm_gc/libatomic_ops/src/atomic_ops/sysdeps/msftc
cvs diff: Diffing boehm_gc/libatomic_ops/src/atomic_ops/sysdeps/sunc
cvs diff: Diffing boehm_gc/libatomic_ops/tests
cvs diff: Diffing boehm_gc/libatomic_ops-1.2
cvs diff: Diffing boehm_gc/libatomic_ops-1.2/doc
cvs diff: Diffing boehm_gc/libatomic_ops-1.2/src
cvs diff: Diffing boehm_gc/libatomic_ops-1.2/src/atomic_ops
cvs diff: Diffing boehm_gc/libatomic_ops-1.2/src/atomic_ops/sysdeps
cvs diff: Diffing boehm_gc/libatomic_ops-1.2/tests
cvs diff: Diffing boehm_gc/m4
cvs diff: Diffing boehm_gc/tests
cvs diff: Diffing browser
cvs diff: Diffing bytecode
cvs diff: Diffing compiler
Index: compiler/add_pragma.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/add_pragma.m,v
retrieving revision 1.132
diff -u -b -r1.132 add_pragma.m
--- compiler/add_pragma.m	10 Sep 2012 17:08:56 -0000	1.132
+++ compiler/add_pragma.m	7 Oct 2012 11:13:08 -0000
@@ -2097,7 +2097,7 @@
         PredIds = [_, _ | _],
         Pieces = [words("Error: ambiguous predicate name"),
             simple_call(simple_call_id(PredOrFunc, SymName, Arity)),
-            words("in"), fixed("`pragma termination_info'."), nl],
+            words("in"), quote("pragma termination_info"), suffix("."), nl],
         Msg = simple_msg(Context, [always(Pieces)]),
         Spec = error_spec(severity_error, phase_parse_tree_to_hlds, [Msg]),
         !:Specs = [Spec | !.Specs]
@@ -2497,7 +2497,7 @@
                 Pieces = [words("Error:"),
                     quote(":- pragma " ++ EvalMethodStr),
                     words("declaration for undeclared mode of"),
-                    simple_call(SimpleCallId), suffix(".")],
+                    simple_call(SimpleCallId), suffix("."), nl],
                 Msg = simple_msg(Context, [always(Pieces)]),
                 Spec = error_spec(severity_error, phase_parse_tree_to_hlds,
                     [Msg]),
@@ -3001,9 +3001,177 @@
     prog_context::in, module_info::in, module_info::out,
     list(error_spec)::in, list(error_spec)::out) is det.
 
-add_pragma_oisu(_OISUInfo, _Status, _Context, !ModuleInfo, !Specs).
-    % XXX incomplete
-    % OISUInfo = pragma_info_oisu(TypeCtor, Creators, Mutators, Destructors).
+add_pragma_oisu(OISUInfo, Status, Context, !ModuleInfo, !Specs) :-
+    OISUInfo = pragma_info_oisu(TypeCtor, Creators, Mutators, Destructors),
+    some [!OISUSpecs] (
+        !:OISUSpecs = [],
+        ThisModule = status_defined_in_this_module(Status),
+        (
+            ThisModule = no
+        ;
+            ThisModule = yes,
+            Exported = status_is_exported_to_non_submodules(Status),
+            (
+                Exported = yes
+            ;
+                Exported = no,
+                StatusPieces = [quote("pragma oisu"),
+                    words("declarations must always be exported."), nl],
+                StatusMsg = simple_msg(Context, [always(StatusPieces)]),
+                StatusSpec = error_spec(severity_error,
+                    phase_parse_tree_to_hlds, [StatusMsg]),
+                !:OISUSpecs = [StatusSpec | !.OISUSpecs]
+            ),
+
+            module_info_get_type_table(!.ModuleInfo, TypeTable),
+            ( search_type_ctor_defn(TypeTable, TypeCtor, TypeDefn) ->
+                hlds_data.get_type_defn_status(TypeDefn, TypeStatus),
+                ( TypeStatus = status_abstract_exported ->
+                    true
+                ;
+                    TypePieces = [words("The type in a"), quote("pragma oisu"),
+                        words("declaration must always be abstract exported."),
+                        nl],
+                    TypeMsg = simple_msg(Context, [always(TypePieces)]),
+                    TypeSpec = error_spec(severity_error,
+                        phase_parse_tree_to_hlds, [TypeMsg]),
+                    !:OISUSpecs = [TypeSpec | !.OISUSpecs]
+                )
+            ;
+%               TypePieces = [words("The type in this"), quote("pragma oisu"),
+%                   words("declaration is undefined."), nl],
+%               TypeMsg = simple_msg(Context, [always(TypePieces)]),
+%               TypeSpec = error_spec(severity_error, phase_parse_tree_to_hlds,
+%                   [TypeMsg]),
+%               !:OISUSpecs = [TypeSpec | !.OISUSpecs]
+
+                % Module qualification will already have reported the error.
+                % Any message we could generate here would be a duplicate.
+                true
+            )
+        ),
+
+        list.map_foldl2(
+            find_unique_pred_for_oisu(!.ModuleInfo, Context, TypeCtor,
+                "creator"),
+            Creators, CreatorPredIds, 1, _, !OISUSpecs),
+        list.map_foldl2(
+            find_unique_pred_for_oisu(!.ModuleInfo, Context, TypeCtor,
+                "mutator"),
+            Mutators, MutatorPredIds, 1, _, !OISUSpecs),
+        list.map_foldl2(
+            find_unique_pred_for_oisu(!.ModuleInfo, Context, TypeCtor,
+                "destructor"),
+            Destructors, DestructorPredIds, 1, _, !OISUSpecs),
+
+        (
+            !.OISUSpecs = [],
+            OISUPreds = oisu_preds(CreatorPredIds, MutatorPredIds,
+                DestructorPredIds),
+            module_info_get_oisu_map(!.ModuleInfo, OISUMap0),
+            ( map.insert(TypeCtor, OISUPreds, OISUMap0, OISUMap) ->
+                module_info_set_oisu_map(OISUMap, !ModuleInfo)
+            ;
+                TypeCtor = type_ctor(TypeName, TypeArity),
+                DupPieces = [words("Duplicate"), quote("pragma oisu"),
+                    words("declaration for"),
+                    sym_name_and_arity(TypeName/TypeArity), suffix("."), nl],
+                DupMsg = simple_msg(Context, [always(DupPieces)]),
+                DupSpec = error_spec(severity_error, phase_parse_tree_to_hlds,
+                    [DupMsg]),
+                !:Specs = [DupSpec | !.Specs]
+            )
+        ;
+            !.OISUSpecs = [_ | _],
+            !:Specs = !.OISUSpecs ++ !.Specs
+        )
+    ).
+
+:- pred find_unique_pred_for_oisu(module_info::in, prog_context::in,
+    type_ctor::in, string::in, pred_name_arity::in, pred_id::out,
+    int::in, int::out, list(error_spec)::in, list(error_spec)::out) is det.
+
+find_unique_pred_for_oisu(ModuleInfo, Context, TypeCtor, Kind,
+        PredNameArity, PredId, !SeqNum, !Specs) :-
+    module_info_get_predicate_table(ModuleInfo, PredicateTable),
+    PredNameArity = pred_name_arity(PredName, PredArity),
+    predicate_table_lookup_sym_arity(PredicateTable, is_fully_qualified,
+        PredName, PredArity, PredIds),
+    (
+        PredIds = [],
+        predicate_table_lookup_sym(PredicateTable, is_fully_qualified,
+            PredName, LooseArityPredIds),
+        (
+            LooseArityPredIds = [],
+            TypeCtor = type_ctor(TypeName, TypeArity),
+            Pieces = [words("In the"), nth_fixed(!.SeqNum),
+                fixed(Kind), words("predicate specification"),
+                words("within the"), quote("pragma oisu"),
+                words("declaration for"),
+                sym_name_and_arity(TypeName/TypeArity), suffix(":"), nl,
+                words("error: predicate"),
+                sym_name_and_arity(PredName/PredArity),
+                words("is undefined."), nl],
+            Msg = simple_msg(Context, [always(Pieces)]),
+            Spec = error_spec(severity_error, phase_parse_tree_to_hlds, [Msg])
+        ;
+            LooseArityPredIds = [_ | _],
+            list.map(lookup_pred_orig_arity(ModuleInfo),
+                LooseArityPredIds, ArityPieces),
+            list.sort_and_remove_dups(ArityPieces, SortedArityPieces),
+            (
+                SortedArityPieces = [],
+                unexpected($module, $pred, "no arity pieces")
+            ;
+                SortedArityPieces = [_],
+                ExpArities = SortedArityPieces
+            ;
+                SortedArityPieces = [_, _ | _],
+                ExpArities = [words("one of") |
+                    component_list_to_pieces(SortedArityPieces)]
+            ),
+            TypeCtor = type_ctor(TypeName, TypeArity),
+            Pieces = [words("In the"), nth_fixed(!.SeqNum),
+                fixed(Kind), words("predicate specification"),
+                words("within the"), quote("pragma oisu"),
+                words("declaration for"),
+                sym_name_and_arity(TypeName/TypeArity), suffix(":"), nl,
+                words("error: predicate"),
+                sym_name_and_arity(PredName/PredArity),
+                words("has the wrong arity."),
+                words("Actual arity is"), int_fixed(PredArity), suffix(","),
+                words("expected arity is")] ++ ExpArities ++ [suffix("."), nl],
+            Msg = simple_msg(Context, [always(Pieces)]),
+            Spec = error_spec(severity_error, phase_parse_tree_to_hlds, [Msg])
+        ),
+        !:Specs = [Spec | !.Specs],
+        PredId = invalid_pred_id
+    ;
+        PredIds = [PredId]
+    ;
+        PredIds = [_, _ | _],
+        TypeCtor = type_ctor(TypeName, TypeArity),
+        Pieces = [words("In the"), nth_fixed(!.SeqNum),
+            fixed(Kind), words("predicate specification"),
+            words("within the"), quote("pragma oisu"),
+            words("declaration for"),
+            sym_name_and_arity(TypeName/TypeArity), suffix(":"), nl,
+            words("error: ambiguous predicate name"),
+            sym_name_and_arity(PredName/PredArity), suffix("."), nl],
+        Msg = simple_msg(Context, [always(Pieces)]),
+        Spec = error_spec(severity_error, phase_parse_tree_to_hlds, [Msg]),
+        !:Specs = [Spec | !.Specs],
+        PredId = invalid_pred_id
+    ),
+    !:SeqNum = !.SeqNum + 1.
+
+:- pred lookup_pred_orig_arity(module_info::in, pred_id::in,
+    format_component::out) is det.
+
+lookup_pred_orig_arity(ModuleInfo, PredId, Piece) :-
+    module_info_pred_info(ModuleInfo, PredId, PredInfo),
+    OrigArity = pred_info_orig_arity(PredInfo),
+    Piece = int_fixed(OrigArity).
 
 %---------------------------------------------------------------------------%
 
@@ -3199,7 +3367,7 @@
         (
             AllowDefnOfBuiltin = no,
             Msg = simple_msg(Context,
-                [always([words("Error: foreign_proc for builtin.")])]),
+                [always([words("Error: foreign_proc for builtin."), nl])]),
             Spec = error_spec(severity_error, phase_parse_tree_to_hlds, [Msg]),
             !:Specs = [Spec | !.Specs]
         ;
@@ -3278,12 +3446,12 @@
             MultipleArgs = [MultipleArg],
             Pieces2 = [words("error: variable"),
                 quote(mercury_var_to_string(PVarSet, no, MultipleArg)),
-                words("occurs multiple times in the argument list.")]
+                words("occurs multiple times in the argument list."), nl]
         ;
             MultipleArgs = [_, _ | _],
             Pieces2 = [words("error: variables"),
                 quote(mercury_vars_to_string(PVarSet, no, MultipleArgs)),
-                words("occur multiple times in the argument list.")]
+                words("occur multiple times in the argument list."), nl]
         ),
         Msg = simple_msg(Context, [always(Pieces1 ++ Pieces2)]),
         Spec = error_spec(severity_error, phase_parse_tree_to_hlds, [Msg]),
@@ -3514,17 +3682,14 @@
                     % out foreign_procs in such languages way before we get
                     % here.
                     ( OldLang = NewLang ->
-                        PiecesA = [
-                            words("Error: multiple clauses for"),
+                        PiecesA = [words("Error: multiple clauses for"),
                             p_or_f(PredOrFunc),
                             sym_name_and_arity(PredName / Arity),
                             words("in language"),
                             words(foreign_language_string(OldLang)),
-                            suffix("."), nl
-                        ],
-                        PiecesB = [
-                            words("The first occurrence was here.")
-                        ],
+                            suffix("."), nl],
+                        PiecesB = [words("The first occurrence was here."),
+                            nl],
                         MsgA = simple_msg(NewContext, [always(PiecesA)]),
                         MsgB = error_msg(yes(ClauseContext), treat_as_first, 0,
                             [always(PiecesB)]),
@@ -3578,7 +3743,7 @@
         (
             IsConcurrencySupported = no,
             Pieces = [words("Error: this module must be compiled in a grade"),
-                words("that supports concurrent execution.")],
+                words("that supports concurrent execution."), nl],
             Msg = simple_msg(Context, [always(Pieces)]),
             Spec = error_spec(severity_error, phase_parse_tree_to_hlds, [Msg]),
             !:Specs = [Spec | !.Specs]
@@ -3592,10 +3757,10 @@
         (
             SinglePrecFloat = no,
             Pieces = [words("Error: this module must be compiled in a grade"),
-                words("that uses single precision floats.")],
+                words("that uses single precision floats."), nl],
             VerbosePieces = [words("Grades that use single precision floats"),
                 words("contain the grade modifier"),
-                quote("spf"), suffix(".")],
+                quote("spf"), suffix("."), nl],
             Msg = simple_msg(Context,
                 [always(Pieces), verbose_only(VerbosePieces)]),
             Spec = error_spec(severity_error, phase_parse_tree_to_hlds, [Msg]),
@@ -3610,10 +3775,10 @@
         (
             SinglePrecFloat = yes,
             Pieces = [words("Error: this module must be compiled in a grade"),
-                words("that uses double precision floats.")],
+                words("that uses double precision floats."), nl],
             VerbosePieces = [words("Grades that use double precision floats"),
                 words("do not contain the grade modifier"),
-                quote("spf"), suffix(".")],
+                quote("spf"), suffix("."), nl],
             Msg = simple_msg(Context,
                 [always(Pieces), verbose_only(VerbosePieces)]),
             Spec = error_spec(severity_error, phase_parse_tree_to_hlds, [Msg]),
@@ -3627,7 +3792,7 @@
         (
             IsTablingSupported = no,
             Pieces = [words("Error: this module must be compiled in a grade"),
-                words("that supports memoisation.")],
+                words("that supports memoisation."), nl],
             Msg = simple_msg(Context, [always(Pieces)]),
             Spec = error_spec(severity_error, phase_parse_tree_to_hlds, [Msg]),
             !:Specs = [Spec | !.Specs]
@@ -3640,7 +3805,7 @@
         (
             IsParConjSupported = no,
             Pieces = [words("Error: this module must be compiled in a grade"),
-                words("that supports executing conjuntions in parallel.")],
+                words("that supports executing conjuntions in parallel."), nl],
             Msg = simple_msg(Context, [always(Pieces)]),
             Spec = error_spec(severity_error, phase_parse_tree_to_hlds, [Msg]),
             !:Specs = [Spec | !.Specs]
@@ -3656,7 +3821,7 @@
                 words("that supports trailing.")],
             VerbosePieces = [words("Grades that support trailing contain"),
                 words("the grade modifiers"), quote("tr"),
-                words("or"), quote("trseg"), suffix(".")],
+                words("or"), quote("trseg"), suffix("."), nl],
             Msg = simple_msg(Context,
                 [always(Pieces), verbose_only(VerbosePieces)]),
             Spec = error_spec(severity_error, phase_parse_tree_to_hlds, [Msg]),
@@ -3677,7 +3842,7 @@
             true
         ;
             Pieces = [words("Error: this module must be compiled using"),
-                words("the strict sequential semantics.")],
+                words("the strict sequential semantics."), nl],
             Msg = simple_msg(Context, [always(Pieces)]),
             Spec = error_spec(severity_error, phase_parse_tree_to_hlds, [Msg]),
             !:Specs = [Spec | !.Specs]
@@ -3702,7 +3867,7 @@
             ; GC_Method = gc_none
             ),
             Pieces = [words("Error: this module must be compiled in a grade"),
-                words("that uses conservative garbage collection.")],
+                words("that uses conservative garbage collection."), nl],
             Msg = simple_msg(Context, [always(Pieces)]),
             Spec = error_spec(severity_error, phase_parse_tree_to_hlds, [Msg]),
             !:Specs = [Spec | !.Specs]
Index: compiler/check_hlds.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/check_hlds.m,v
retrieving revision 1.24
diff -u -b -r1.24 check_hlds.m
--- compiler/check_hlds.m	20 Dec 2010 07:47:28 -0000	1.24
+++ compiler/check_hlds.m	7 Oct 2012 11:13:08 -0000
@@ -76,6 +76,9 @@
 % Stratification.
 :- include_module stratify.
 
+% Order independent state update pragmas.
+:- include_module oisu_check.
+
 % Expand try goals
 :- include_module try_expand.
 
Index: compiler/error_util.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/error_util.m,v
retrieving revision 1.81
diff -u -b -r1.81 error_util.m
--- compiler/error_util.m	8 Jun 2012 15:46:20 -0000	1.81
+++ compiler/error_util.m	7 Oct 2012 11:13:08 -0000
@@ -113,6 +113,7 @@
     ;       phase_mode_check(mode_report_control)
     ;       phase_purity_check
     ;       phase_detism_check
+    ;       phase_oisu_check
     ;       phase_simplify(mode_report_control)
     ;       phase_dead_code
     ;       phase_termination_analysis
@@ -661,6 +662,7 @@
 get_maybe_mode_report_control(phase_mode_check(Control)) = yes(Control).
 get_maybe_mode_report_control(phase_purity_check) = no.
 get_maybe_mode_report_control(phase_detism_check) = no.
+get_maybe_mode_report_control(phase_oisu_check) = no.
 get_maybe_mode_report_control(phase_simplify(Control)) = yes(Control).
 get_maybe_mode_report_control(phase_dead_code) = no.
 get_maybe_mode_report_control(phase_termination_analysis) = no.
Index: compiler/hlds_goal.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/hlds_goal.m,v
retrieving revision 1.239
diff -u -b -r1.239 hlds_goal.m
--- compiler/hlds_goal.m	2 Jul 2012 01:16:34 -0000	1.239
+++ compiler/hlds_goal.m	7 Oct 2012 11:13:10 -0000
@@ -1683,7 +1683,8 @@
     %
 :- pred negate_goal(hlds_goal::in, hlds_goal_info::in, hlds_goal::out) is det.
 
-    % Return yes if goal(s) contain any foreign code
+    % Returns yes if the goal, or subgoal contained within, contains
+    % any foreign code.
     %
 :- func goal_has_foreign(hlds_goal) = bool.
 
@@ -3261,9 +3262,6 @@
 
 %-----------------------------------------------------------------------------%
 
-    % Returns yes if a goal (or subgoal contained within) contains
-    % any foreign code.
-    %
 goal_has_foreign(Goal) = HasForeign :-
     Goal = hlds_goal(GoalExpr, _),
     (
Index: compiler/hlds_module.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/hlds_module.m,v
retrieving revision 1.178
diff -u -b -r1.178 hlds_module.m
--- compiler/hlds_module.m	10 Sep 2012 17:08:57 -0000	1.178
+++ compiler/hlds_module.m	7 Oct 2012 11:13:11 -0000
@@ -207,6 +207,20 @@
 
 %-----------------------------------------------------------------------------%
 %
+% Types for order-independent state update.
+%
+
+:- type oisu_map == map(type_ctor, oisu_preds).
+
+:- type oisu_preds
+    --->    oisu_preds(
+                op_creators     :: list(pred_id),
+                op_mutators     :: list(pred_id),
+                op_destructors  :: list(pred_id)
+            ).
+
+%-----------------------------------------------------------------------------%
+%
 % Various predicates for manipulating the module_info data structure.
 %
 
@@ -525,6 +539,17 @@
 :- pred module_info_set_event_set(event_set::in,
     module_info::in, module_info::out) is det.
 
+:- pred module_info_get_oisu_map(module_info::in, oisu_map::out) is det.
+
+:- pred module_info_set_oisu_map(oisu_map::in,
+    module_info::in, module_info::out) is det.
+
+:- pred module_info_get_oisu_procs(module_info::in, set(pred_proc_id)::out)
+    is det.
+
+:- pred module_info_set_oisu_procs(set(pred_proc_id)::in,
+    module_info::in, module_info::out) is det.
+
 :- pred module_info_get_const_struct_db(module_info::in,
     const_struct_db::out) is det.
 
@@ -841,6 +866,14 @@
 
                 msi_event_set                   :: event_set,
 
+                % The set of visible declarations about order-independent
+                % state update.
+                msi_oisu_map                    :: oisu_map,
+
+                % The set of procedures defined in this module that
+                % have OISU arguments.
+                msi_oisu_procs                  :: set(pred_proc_id),
+
                 % The database of constant structures the code generator
                 % will generate independently, outside all the procedures
                 % of the program.
@@ -907,6 +940,8 @@
     set.init(InterfaceModuleSpecs),
     ExportedEnums = [],
     EventSet = event_set("", map.init),
+    map.init(OISUMap),
+    set.init(OISUProcs),
     const_struct_db_init(Globals, ConstStructDb),
     TSStringTableSize = 0,
     TSRevStringTable = [],
@@ -923,7 +958,7 @@
         MaybeComplexityMap, ComplexityProcInfos,
         AnalysisInfo, UserInitPredCNames, UserFinalPredCNames,
         StructureReusePredIds, UsedModules, InterfaceModuleSpecs,
-        ExportedEnums, EventSet, ConstStructDb,
+        ExportedEnums, EventSet, OISUMap, OISUProcs, ConstStructDb,
         TSStringTableSize, TSRevStringTable),
 
     predicate_table_init(PredicateTable),
@@ -1057,6 +1092,8 @@
     MI ^ mi_sub_info ^ msi_interface_module_specifiers).
 module_info_get_exported_enums(MI, MI ^ mi_sub_info ^ msi_exported_enums).
 module_info_get_event_set(MI, MI ^ mi_sub_info ^ msi_event_set).
+module_info_get_oisu_map(MI, MI ^ mi_sub_info ^ msi_oisu_map).
+module_info_get_oisu_procs(MI, MI ^ mi_sub_info ^ msi_oisu_procs).
 module_info_get_const_struct_db(MI, MI ^ mi_sub_info ^ msi_const_struct_db).
 module_info_get_ts_rev_string_table(MI,
     MI ^ mi_sub_info ^ msi_ts_string_table_size,
@@ -1217,6 +1254,10 @@
     !MI ^ mi_sub_info ^ msi_used_modules := UsedModules.
 module_info_set_event_set(EventSet, !MI) :-
     !MI ^ mi_sub_info ^ msi_event_set := EventSet.
+module_info_set_oisu_map(OISUMap, !MI) :-
+    !MI ^ mi_sub_info ^ msi_oisu_map := OISUMap.
+module_info_set_oisu_procs(OISUProcs, !MI) :-
+    !MI ^ mi_sub_info ^ msi_oisu_procs := OISUProcs.
 module_info_set_const_struct_db(ConstStructDb, !MI) :-
     !MI ^ mi_sub_info ^ msi_const_struct_db := ConstStructDb.
 module_info_set_ts_rev_string_table(Size, RevTable, !MI) :-
Index: compiler/hlds_pred.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/hlds_pred.m,v
retrieving revision 1.283
diff -u -b -r1.283 hlds_pred.m
--- compiler/hlds_pred.m	11 Jul 2012 04:00:59 -0000	1.283
+++ compiler/hlds_pred.m	7 Oct 2012 11:13:12 -0000
@@ -518,25 +518,31 @@
     --->    origin_special_pred(special_pred)
                 % If the predicate is a unify, compare, index or initialisation
                 % predicate, specify which one, and for which type constructor.
+
     ;       origin_instance_method(sym_name, instance_method_constraints)
                 % The predicate is a class method implementation. Record
                 % the method name and extra information about the class
                 % context to allow polymorphism.m to correctly set up the
                 % extra type_info and typeclass_info arguments.
+
     ;       origin_transformed(pred_transformation, pred_origin, pred_id)
                 % The predicate is a transformed version of another predicate,
                 % whose origin and identity are given by the second and third
                 % arguments.
+
     ;       origin_created(pred_creation)
                 % The predicate was created by the compiler, and there is no
                 % information available on where it came from.
+
     ;       origin_assertion(string, int)
                 % The predicate represents an assertion.
+
     ;       origin_lambda(string, int, int)
                 % The predicate is a higher-order manifest constant.
                 % The arguments specify its location in the source, as a
                 % filename/line number pair, and a sequence number used to
                 % distinguish multiple lambdas on the same line.
+
     ;       origin_user(sym_name).
                 % The predicate is a normal user-written predicate;
                 % the string is its name.
@@ -1988,6 +1994,11 @@
     --->    tail_call_events
     ;       no_tail_call_events.
 
+:- type oisu_pred_kind_for
+    --->    oisu_creator_for(type_ctor)
+    ;       oisu_mutator_for(type_ctor)
+    ;       oisu_destructor_for(type_ctor).
+
     % Predicates to get fields of proc_infos.
 
 :- pred proc_info_get_context(proc_info::in, prog_context::out) is det.
@@ -2042,6 +2053,8 @@
     map(prog_var, string)::out) is det.
 :- pred proc_info_get_statevar_warnings(proc_info::in, list(error_spec)::out)
     is det.
+:- pred proc_info_get_oisu_kind_fors(proc_info::in,
+    list(oisu_pred_kind_for)::out) is det.
 
     % Predicates to set fields of proc_infos.
 
@@ -2110,6 +2123,8 @@
     proc_info::in, proc_info::out) is det.
 :- pred proc_info_set_statevar_warnings(list(error_spec)::in,
     proc_info::in, proc_info::out) is det.
+:- pred proc_info_set_oisu_kind_fors(list(oisu_pred_kind_for)::in,
+    proc_info::in, proc_info::out) is det.
 
 :- pred proc_info_get_termination2_info(proc_info::in,
     termination2_info::out) is det.
@@ -2455,7 +2470,10 @@
 
                 % Structure reuse conditions obtained by the structure reuse
                 % analysis (CTGC).
-                structure_reuse             :: structure_reuse_info
+                structure_reuse             :: structure_reuse_info,
+
+                % XXX document me
+                psi_oisu_kind_fors          :: list(oisu_pred_kind_for)
         ).
 
 :- type structure_sharing_info
@@ -2586,7 +2604,7 @@
     ProcSubInfo = proc_sub_info(DetismDecl, no, no, Term2Info, IsAddressTaken,
         StackSlots, RegR_HeadVars, ArgInfo, InitialLiveness, no, no,
         no, no_tail_call_events, no, no, no, no, no, no, VarNameRemap, [],
-        SharingInfo, ReuseInfo),
+        SharingInfo, ReuseInfo, []),
     ProcInfo = proc_info(MContext, BodyVarSet, BodyTypes, HeadVars, InstVarSet,
         DeclaredModes, Modes, no, MaybeArgLives, MaybeDet, InferredDet,
         ClauseBody, CanProcess, ModeErrors, RttiVarMaps, eval_normal,
@@ -2620,7 +2638,7 @@
     ProcSubInfo = proc_sub_info(DetismDecl, no, no, Term2Info, IsAddressTaken,
         StackSlots, RegR_HeadVars, no, Liveness, no, no, no,
         no_tail_call_events, no, no, no, no, no, no, VarNameRemap, [],
-        SharingInfo, ReuseInfo),
+        SharingInfo, ReuseInfo, []),
     ProcInfo = proc_info(Context, VarSet, VarTypes, HeadVars,
         InstVarSet, no, HeadModes, no, MaybeHeadLives,
         MaybeDeclaredDetism, Detism, Goal, yes, ModeErrors,
@@ -2673,6 +2691,7 @@
 proc_info_get_maybe_untuple_info(PI, PI ^ proc_sub_info ^ maybe_untuple_info).
 proc_info_get_var_name_remap(PI, PI ^ proc_sub_info ^ proc_var_name_remap).
 proc_info_get_statevar_warnings(PI, PI ^ proc_sub_info ^ statevar_warnings).
+proc_info_get_oisu_kind_fors(PI, PI ^ proc_sub_info ^ psi_oisu_kind_fors).
 
 proc_info_set_varset(VS, !PI) :-
     !PI ^ prog_varset := VS.
@@ -2738,6 +2757,8 @@
     !PI ^ proc_sub_info ^ proc_var_name_remap := VNR.
 proc_info_set_statevar_warnings(SVW, !PI) :-
     !PI ^ proc_sub_info ^ statevar_warnings := SVW.
+proc_info_set_oisu_kind_fors(KFs, !PI) :-
+    !PI ^ proc_sub_info ^ psi_oisu_kind_fors := KFs.
 
 proc_info_head_modes_constraint(ProcInfo, HeadModesConstraint) :-
     MaybeHeadModesConstraint = ProcInfo ^ maybe_head_modes_constraint,
Index: compiler/make_hlds_passes.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/make_hlds_passes.m,v
retrieving revision 1.123
diff -u -b -r1.123 make_hlds_passes.m
--- compiler/make_hlds_passes.m	10 Sep 2012 17:08:57 -0000	1.123
+++ compiler/make_hlds_passes.m	7 Oct 2012 11:13:14 -0000
@@ -180,8 +180,8 @@
 
             % Add constructors and special preds to the HLDS. This must be done
             % after adding all type and `:- pragma foreign_type' declarations.
-            % If there were errors in foreign type type declarations, doing this
-            % may cause a compiler abort.
+            % If there were errors in foreign type type declarations, doing
+            % this may cause a compiler abort.
             foldl3_over_type_ctor_defns(process_type_defn, !.TypeTable,
                 no, InvalidTypes2, !ModuleInfo, !Specs)
         )
@@ -1550,8 +1550,8 @@
             ->
                 module_info_new_user_init_pred(SymName, Arity, CName,
                     !ModuleInfo),
-                PredNameModesPF = pred_name_modes_pf(SymName, 
-                    [], pf_predicate),
+                PredNameModesPF = pred_name_modes_pf(SymName, [],
+                    pf_predicate),
                 FPEInfo = pragma_info_foreign_proc_export(ExportLang,
                     PredNameModesPF, CName),
                 ExportPragma = pragma_foreign_proc_export(FPEInfo),
Index: compiler/mercury_compile_front_end.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/mercury_compile_front_end.m,v
retrieving revision 1.11
diff -u -b -r1.11 mercury_compile_front_end.m
--- compiler/mercury_compile_front_end.m	16 Jun 2011 06:42:14 -0000	1.11
+++ compiler/mercury_compile_front_end.m	7 Oct 2012 11:13:14 -0000
@@ -79,6 +79,7 @@
 :- import_module check_hlds.inst_check.
 :- import_module check_hlds.mode_constraints.
 :- import_module check_hlds.modes.
+:- import_module check_hlds.oisu_check.
 :- import_module check_hlds.polymorphism.
 :- import_module check_hlds.post_typecheck.
 :- import_module check_hlds.purity.
@@ -96,6 +97,9 @@
 :- import_module libs.file_util.
 :- import_module libs.globals.
 :- import_module libs.options.
+:- import_module mdbcomp.
+:- import_module mdbcomp.prim_data.
+:- import_module parse_tree.prog_data.
 :- import_module parse_tree.file_names.
 :- import_module parse_tree.module_cmds.
 :- import_module top_level.mercury_compile_middle_passes.
@@ -105,6 +109,7 @@
 :- import_module benchmarking.
 :- import_module bool.
 :- import_module int.
+:- import_module map.
 :- import_module maybe.
 :- import_module pair.
 :- import_module require.
@@ -494,6 +499,10 @@
             !Specs, !IO),
         maybe_dump_hlds(!.HLDS, 60, "stratification", !DumpInfo, !IO),
 
+        check_oisu_pragmas(Verbose, Stats, !HLDS, FoundOISUError,
+            !Specs, !IO),
+        maybe_dump_hlds(!.HLDS, 60, "stratification", !DumpInfo, !IO),
+
         process_try_goals(Verbose, Stats, !HLDS, FoundTryError, !Specs, !IO),
         maybe_dump_hlds(!.HLDS, 62, "try", !DumpInfo, !IO),
 
@@ -511,6 +520,7 @@
             FoundModeError = no,
             FoundUniqError = no,
             FoundStratError = no,
+            FoundOISUError = no,
             FoundTryError = no,
             NumErrors = 0,
             % Strictly speaking, we shouldn't need to check the exit status.
@@ -808,7 +818,7 @@
         maybe_write_out_errors(Verbose, Globals, !HLDS, !Specs, !IO),
         maybe_write_string(Verbose,
             "% Checking stratification...\n", !IO),
-        check_stratification(!HLDS, [], StratifySpecs),
+        check_module_for_stratification(!HLDS, StratifySpecs),
         !:Specs = StratifySpecs ++ !.Specs,
         FoundError = contains_errors(Globals, StratifySpecs),
         maybe_write_out_errors(Verbose, Globals, !HLDS, !Specs, !IO),
@@ -827,6 +837,50 @@
 
 %-----------------------------------------------------------------------------%
 
+:- pred check_oisu_pragmas(bool::in, bool::in,
+    module_info::in, module_info::out, bool::out,
+    list(error_spec)::in, list(error_spec)::out, io::di, io::uo) is det.
+
+check_oisu_pragmas(Verbose, Stats, !HLDS, FoundError, !Specs, !IO) :-
+    module_info_get_oisu_map(!.HLDS, OISUMap),
+    map.to_assoc_list(OISUMap, OISUPairs),
+    module_info_get_name(!.HLDS, ModuleName),
+    list.filter(type_ctor_is_defined_in_this_module(ModuleName),
+        OISUPairs, ModuleOISUPairs),
+    (
+        ModuleOISUPairs = [_ | _],
+        module_info_get_globals(!.HLDS, Globals),
+        maybe_write_out_errors(Verbose, Globals, !HLDS, !Specs, !IO),
+        maybe_write_string(Verbose,
+            "% Checking oisu pragmas...\n", !IO),
+        check_oisu_pragmas_for_module(ModuleOISUPairs, !HLDS, OISUSpecs),
+        !:Specs = OISUSpecs ++ !.Specs,
+        FoundError = contains_errors(Globals, OISUSpecs),
+        maybe_write_out_errors(Verbose, Globals, !HLDS, !Specs, !IO),
+        (
+            FoundError = yes,
+            maybe_write_string(Verbose,
+                "% Program contains oisu pragma error(s).\n", !IO)
+        ;
+            FoundError = no,
+            maybe_write_string(Verbose, "% done.\n", !IO)
+        ),
+        maybe_report_stats(Stats, !IO)
+    ;
+        ModuleOISUPairs = [],
+        FoundError = no
+    ).
+
+:- pred type_ctor_is_defined_in_this_module(module_name::in,
+    pair(type_ctor, oisu_preds)::in) is semidet.
+
+type_ctor_is_defined_in_this_module(ModuleName, TypeCtor - _) :-
+    TypeCtor = type_ctor(TypeSymName, _TypeArity),
+    TypeSymName = qualified(TypeModuleName, _TypeName),
+    ModuleName = TypeModuleName.
+
+%-----------------------------------------------------------------------------%
+
 :- pred process_try_goals(bool::in, bool::in,
     module_info::in, module_info::out, bool::out,
     list(error_spec)::in, list(error_spec)::out, io::di, io::uo) is det.
Index: compiler/mercury_to_mercury.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/mercury_to_mercury.m,v
retrieving revision 1.363
diff -u -b -r1.363 mercury_to_mercury.m
--- compiler/mercury_to_mercury.m	10 Sep 2012 13:33:07 -0000	1.363
+++ compiler/mercury_to_mercury.m	7 Oct 2012 11:13:17 -0000
@@ -3902,7 +3902,6 @@
         DestructorPreds),
     add_string(":- pragma oisu(", !U),
     TypeCtor = type_ctor(TypeName, TypeArity),
-    add_string(":- pragma reserve_tag(", !U),
     mercury_format_bracketed_sym_name_ngt(TypeName, next_to_graphic_token, !U),
     add_string("/", !U),
     add_int(TypeArity, !U),
@@ -3915,7 +3914,7 @@
     add_string("\t]),\n", !U),
     add_string("\tdestructors([\n", !U),
     mercury_format_pred_name_arity_list(DestructorPreds, !U),
-    add_string("\t]).\n", !U),
+    add_string("\t])\n", !U),
     add_string(").\n", !U).
 
 :- pred mercury_format_pred_name_arity_list(list(pred_name_arity)::in,
Index: compiler/module_qual.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/module_qual.m,v
retrieving revision 1.195
diff -u -b -r1.195 module_qual.m
--- compiler/module_qual.m	10 Sep 2012 13:33:07 -0000	1.195
+++ compiler/module_qual.m	7 Oct 2012 11:13:20 -0000
@@ -857,7 +857,7 @@
     ;
         Item0 = item_pragma(ItemPragma0),
         ItemPragma0 = item_pragma_info(Origin, Pragma0, Context, SeqNum),
-        mq_info_set_error_context(mqec_pragma - Context, !Info),
+        mq_info_set_error_context(mqec_pragma(Pragma0) - Context, !Info),
         qualify_pragma(Pragma0, Pragma, !Info, !Specs),
         ItemPragma = item_pragma_info(Origin, Pragma, Context, SeqNum),
         Item = item_pragma(ItemPragma),
@@ -1792,7 +1792,7 @@
     ;       mqec_mode(mq_id)
     ;       mqec_pred_or_func(pred_or_func, mq_id)
     ;       mqec_pred_or_func_mode(maybe(pred_or_func), mq_id)
-    ;       mqec_pragma
+    ;       mqec_pragma(pragma_type)
     ;       mqec_lambda_expr
     ;       mqec_clause_mode_annotation
     ;       mqec_type_qual
@@ -1909,8 +1909,108 @@
     [words("mode declaration for lambda expression")].
 mq_error_context_to_pieces(mqec_clause_mode_annotation) =
     [words("clause mode annotation")].
-mq_error_context_to_pieces(mqec_pragma) =
-    [words("pragma")].
+mq_error_context_to_pieces(mqec_pragma(Pragma)) =
+        [words("pragma"), words(PragmaName)] :-
+    (
+        Pragma = pragma_foreign_decl(_),
+        PragmaName = "foreign_decl"
+    ;
+        Pragma = pragma_foreign_code(_),
+        PragmaName = "foreign_code"
+    ;
+        Pragma = pragma_foreign_proc(_),
+        PragmaName = "foreign_proc"
+    ;
+        Pragma = pragma_foreign_import_module(_),
+        PragmaName = "foreign_import_module"
+    ;
+        Pragma = pragma_foreign_proc_export(_),
+        PragmaName = "foreign_proc_export"
+    ;
+        Pragma = pragma_foreign_export_enum(_),
+        PragmaName = "foreign_export_enum"
+    ;
+        Pragma = pragma_foreign_enum(_),
+        PragmaName = "foreign_enum"
+    ;
+        Pragma = pragma_type_spec(_),
+        PragmaName = "type_spec"
+    ;
+        Pragma = pragma_inline(_),
+        PragmaName = "inline"
+    ;
+        Pragma = pragma_no_inline(_),
+        PragmaName = "no_inline"
+    ;
+        Pragma = pragma_unused_args(_),
+        PragmaName = "unused_args"
+    ;
+        Pragma = pragma_exceptions(_),
+        PragmaName = "exceptions"
+    ;
+        Pragma = pragma_trailing_info(_),
+        PragmaName = "trailing_info"
+    ;
+        Pragma = pragma_mm_tabling_info(_),
+        PragmaName = "mm_tabling_info"
+    ;
+        Pragma = pragma_obsolete(_),
+        PragmaName = "obsolete"
+    ;
+        Pragma = pragma_no_detism_warning(_),
+        PragmaName = "no_detism_warning"
+    ;
+        Pragma = pragma_source_file(_),
+        PragmaName = "source_file"
+    ;
+        Pragma = pragma_tabled(_),
+        PragmaName = "tabled"
+    ;
+        Pragma = pragma_fact_table(_),
+        PragmaName = "fact_table"
+    ;
+        Pragma = pragma_reserve_tag(_),
+        PragmaName = "reserve_tag"
+    ;
+        Pragma = pragma_oisu(_),
+        PragmaName = "oisu"
+    ;
+        Pragma = pragma_promise_eqv_clauses(_),
+        PragmaName = "promise_equivalent_clauses"
+    ;
+        Pragma = pragma_promise_pure(_),
+        PragmaName = "promise_pure"
+    ;
+        Pragma = pragma_promise_semipure(_),
+        PragmaName = "promise_semipure"
+    ;
+        Pragma = pragma_termination_info(_),
+        PragmaName = "termination_info"
+    ;
+        Pragma = pragma_termination2_info(_),
+        PragmaName = "termination2_info"
+    ;
+        Pragma = pragma_terminates(_),
+        PragmaName = "terminates"
+    ;
+        Pragma = pragma_does_not_terminate(_),
+        PragmaName = "does_not_terminate"
+    ;
+        Pragma = pragma_check_termination(_),
+        PragmaName = "check_termination"
+    ;
+        Pragma = pragma_mode_check_clauses(_),
+        PragmaName = "mode_check_clauses"
+    ;
+        Pragma = pragma_structure_sharing(_),
+        PragmaName = "structure_sharing"
+    ;
+        Pragma = pragma_structure_reuse(_),
+        PragmaName = "structure_reuse"
+    ;
+        Pragma = pragma_require_feature_set(_),
+        PragmaName = "require_feature_set"
+    ).
 mq_error_context_to_pieces(mqec_type_qual) =
     [words("explicit type qualification")].
 mq_error_context_to_pieces(mqec_class(Id)) =
@@ -1918,12 +2018,7 @@
 mq_error_context_to_pieces(mqec_instance(Id)) =
     [words("declaration of instance of typeclass"), wrap_id(Id)].
 mq_error_context_to_pieces(mqec_mutable(Name)) =
-    [
-        words("declaration for mutable "),
-        prefix("`"),
-        words(Name),
-        suffix("'")
-    ].
+    [words("declaration for mutable "), prefix("`"), words(Name), suffix("'")].
 mq_error_context_to_pieces(mqec_event_spec_attr(EventName, AttrName)) =
     [words("attribute"), quote(AttrName), words("for"), quote(EventName)].
 
Index: compiler/modules.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/modules.m,v
retrieving revision 1.473
diff -u -b -r1.473 modules.m
--- compiler/modules.m	10 Sep 2012 13:33:07 -0000	1.473
+++ compiler/modules.m	7 Oct 2012 11:13:23 -0000
@@ -1672,7 +1672,6 @@
         ; Pragma = pragma_no_detism_warning(_)
         ; Pragma = pragma_no_inline(_)
         ; Pragma = pragma_fact_table(_)
-        ; Pragma = pragma_oisu(_)
         ; Pragma = pragma_tabled(_)
         ; Pragma = pragma_promise_pure(_)
         ; Pragma = pragma_promise_semipure(_)
@@ -1703,6 +1702,7 @@
         ; Pragma = pragma_structure_sharing(_)
         ; Pragma = pragma_structure_reuse(_)
         ; Pragma = pragma_mode_check_clauses(_)
+        ; Pragma = pragma_oisu(_)
         ),
         Allowed = yes
     ).
Index: compiler/oisu_check.m
===================================================================
RCS file: compiler/oisu_check.m
diff -N compiler/oisu_check.m
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ compiler/oisu_check.m	7 Oct 2012 11:13:23 -0000
@@ -0,0 +1,448 @@
+%-----------------------------------------------------------------------------%
+% vim: ft=mercury ts=4 sw=4 et
+%-----------------------------------------------------------------------------%
+% Copyright (C) 2012 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: oisu_check.m.
+% Main author: zs.
+%
+% This module checks whether the oisu (order independent state update) pragmas
+% (if any) that are present in the module being compiled satisfy the
+% requirements on them.
+%
+%-----------------------------------------------------------------------------%
+
+:- module check_hlds.oisu_check.
+:- interface.
+
+:- import_module hlds.
+:- import_module hlds.hlds_module.
+:- import_module parse_tree.
+:- import_module parse_tree.error_util.
+:- import_module parse_tree.prog_data.
+
+:- import_module assoc_list.
+:- import_module list.
+
+    % XXX document me
+    %
+:- pred check_oisu_pragmas_for_module(assoc_list(type_ctor, oisu_preds)::in,
+    module_info::in, module_info::out, list(error_spec)::out) is det.
+
+%-----------------------------------------------------------------------------%
+%-----------------------------------------------------------------------------%
+
+:- implementation.
+
+:- import_module check_hlds.mode_util.
+:- import_module hlds.hlds_error_util.
+:- import_module hlds.hlds_pred.
+:- import_module parse_tree.prog_type.
+
+:- import_module bool.
+:- import_module int.
+:- import_module map.
+:- import_module pair.
+:- import_module require.
+:- import_module set.
+:- import_module string.
+
+check_oisu_pragmas_for_module(OISUPairs, !ModuleInfo, Specs) :-
+    map.init(KindMap0),
+    list.foldl(add_type_ctor_to_kind_map, OISUPairs, KindMap0, KindMap),
+    module_info_get_preds(!.ModuleInfo, PredTable0),
+    map.to_assoc_list(PredTable0, Preds0),
+    assoc_list.keys(OISUPairs, OISUTypeCtors),
+    list.map_foldl2(
+        check_local_oisu_pred(!.ModuleInfo, KindMap, OISUTypeCtors),
+        Preds0, Preds, set.init, OISUProcs, [], Specs),
+    map.from_assoc_list(Preds, PredTable),
+    module_info_set_preds(PredTable, !ModuleInfo),
+    module_info_set_oisu_procs(OISUProcs, !ModuleInfo).
+
+%-----------------------------------------------------------------------------%
+
+:- pred add_type_ctor_to_kind_map(pair(type_ctor, oisu_preds)::in,
+    oisu_kind_map::in, oisu_kind_map::out) is det.
+
+add_type_ctor_to_kind_map(TypeCtor - OISUPreds, !KindMap) :-
+    OISUPreds = oisu_preds(CreatorPreds, MutatorPreds, DestructorPreds),
+    list.foldl(add_pred_to_kind_map(TypeCtor, oisu_creator),
+        CreatorPreds, !KindMap),
+    list.foldl(add_pred_to_kind_map(TypeCtor, oisu_mutator),
+        MutatorPreds, !KindMap),
+    list.foldl(add_pred_to_kind_map(TypeCtor, oisu_destructor),
+        DestructorPreds, !KindMap).
+
+:- type oisu_pred_kind
+    --->    oisu_creator
+    ;       oisu_mutator
+    ;       oisu_destructor.
+
+:- type oisu_kind_map == map(pred_id, list(oisu_pred_kind_for)).
+
+:- pred add_pred_to_kind_map(type_ctor::in, oisu_pred_kind::in,
+    pred_id::in, oisu_kind_map::in, oisu_kind_map::out) is det.
+
+add_pred_to_kind_map(TypeCtor, Kind, PredId, !KindMap) :-
+    (
+        Kind = oisu_creator,
+        KindFor = oisu_creator_for(TypeCtor)
+    ;
+        Kind = oisu_mutator,
+        KindFor = oisu_mutator_for(TypeCtor)
+    ;
+        Kind = oisu_destructor,
+        KindFor = oisu_destructor_for(TypeCtor)
+    ),
+    ( map.search(!.KindMap, PredId, OldEntries) ->
+        Entries = [KindFor | OldEntries],
+        map.det_update(PredId, Entries, !KindMap)
+    ;
+        Entries = [KindFor],
+        map.det_insert(PredId, Entries, !KindMap)
+    ).
+
+%-----------------------------------------------------------------------------%
+
+:- pred check_local_oisu_pred(module_info::in, oisu_kind_map::in,
+    list(type_ctor)::in,
+    pair(pred_id, pred_info)::in, pair(pred_id, pred_info)::out,
+    set(pred_proc_id)::in, set(pred_proc_id)::out,
+    list(error_spec)::in, list(error_spec)::out) is det.
+
+check_local_oisu_pred(ModuleInfo, KindMap, OISUTypeCtors,
+        Pair0, Pair, !OISUProcs, !Specs) :-
+    Pair0 = PredId - PredInfo0,
+    pred_info_get_import_status(PredInfo0, Status0),
+    ( Status0 = status_external(StatusPrime) ->
+        Status = StatusPrime
+    ;
+        Status = Status0
+    ),
+    IsDefnInModule = status_defined_in_this_module(Status),
+    (
+        IsDefnInModule = no,
+        Pair = Pair0
+    ;
+        IsDefnInModule = yes,
+        ( map.search(KindMap, PredId, KindFors) ->
+            pred_info_get_procedures(PredInfo0, ProcTable0),
+            map.to_assoc_list(ProcTable0, Procs0),
+            (
+                Procs0 = [],
+                unexpected($module, $pred, "no procedure for local predicate")
+            ;
+                Procs0 = [ProcId - ProcInfo0],
+                pred_info_get_arg_types(PredInfo0, ArgTypes),
+                proc_info_get_argmodes(ProcInfo0, ArgModes),
+                assoc_list.from_corresponding_lists(ArgTypes, ArgModes,
+                    ArgTypesModes),
+                check_arg_oisu_types(ModuleInfo, PredInfo0, KindFors,
+                    OISUTypeCtors, 1, [], ArgTypesModes, !Specs),
+                proc_info_set_oisu_kind_fors(KindFors, ProcInfo0, ProcInfo),
+                Procs = [ProcId - ProcInfo],
+                map.from_assoc_list(Procs, ProcTable),
+                pred_info_set_procedures(ProcTable, PredInfo0, PredInfo),
+                Pair = PredId - PredInfo,
+                set.insert(proc(PredId, ProcId), !OISUProcs)
+            ;
+                Procs0 = [_, _ | _],
+                PredDesc = describe_one_pred_info_name(
+                    should_not_module_qualify, PredInfo0),
+                ProcsPieces = PredDesc ++ [words("is mentioned"),
+                    words("in a"), quote("pragma oisu"), words("declaration,"),
+                    words("so it should have exactly one procedure."), nl],
+                pred_info_get_context(PredInfo0, Context),
+                ProcsMsg = simple_msg(Context, [always(ProcsPieces)]),
+                ProcsSpec = error_spec(severity_error, phase_oisu_check,
+                    [ProcsMsg]),
+                !:Specs = [ProcsSpec | !.Specs],
+                Pair = Pair0
+            )
+        ; 
+            pred_info_get_origin(PredInfo0, Origin),
+            ( Origin = origin_special_pred(_) ->
+                true
+            ;
+                pred_info_get_arg_types(PredInfo0, ArgTypes),
+                check_args_have_no_oisu_types(PredInfo0, OISUTypeCtors,
+                    ArgTypes, !Specs)
+            ),
+            Pair = Pair0
+        )
+    ).
+
+%-----------------------------------------------------------------------------%
+
+:- pred check_arg_oisu_types(module_info::in, pred_info::in,
+    list(oisu_pred_kind_for)::in, list(type_ctor)::in, int::in,
+    list(type_ctor)::in, assoc_list(mer_type, mer_mode)::in,
+    list(error_spec)::in, list(error_spec)::out) is det.
+
+check_arg_oisu_types(ModuleInfo, PredInfo, KindFors, OISUTypeCtors, ArgNum,
+        !.HandledOISUTypeCtors, [TypeMode | TypesModes], !Specs) :-
+    (
+        TypeMode = Type - Mode,
+        type_to_ctor_and_args(Type, TypeCtor, ArgTypes),
+        list.member(TypeCtor, OISUTypeCtors)
+    ->
+        (
+            ArgTypes = []
+        ;
+            ArgTypes = [_ | _],
+            unexpected($module, $pred, "ArgTypes != []")
+        ),
+        ( find_kind_for_oisu_type(KindFors, TypeCtor, ThisKind) ->
+            ( list.member(TypeCtor, !.HandledOISUTypeCtors) ->
+                DupPredDesc = describe_one_pred_info_name(
+                    should_not_module_qualify, PredInfo),
+                DupPieces = [words("The"), nth_fixed(ArgNum),
+                    words("argument of")] ++ DupPredDesc ++
+                    [words("handles a previous handled OISU type."), nl],
+                pred_info_get_context(PredInfo, DupContext),
+                DupMsg = simple_msg(DupContext, [always(DupPieces)]),
+                DupSpec = error_spec(severity_error, phase_oisu_check,
+                    [DupMsg]),
+                !:Specs = [DupSpec | !.Specs],
+                RestArgNum = ArgNum + 1,
+                RestTypesModes = TypesModes
+            ;
+                !:HandledOISUTypeCtors = [TypeCtor | !.HandledOISUTypeCtors],
+                (
+                    ThisKind = oisu_creator,
+                    ( mode_is_output(ModuleInfo, Mode) ->
+                        true
+                    ;
+                        PredDesc = describe_one_pred_info_name(
+                            should_not_module_qualify, PredInfo),
+                        Pieces = [words("The"), nth_fixed(ArgNum),
+                            words("argument of")] ++ PredDesc ++
+                            [words("should be a creator of its OISU type,"),
+                            words("but its mode is not output."), nl],
+                        pred_info_get_context(PredInfo, Context),
+                        Msg = simple_msg(Context, [always(Pieces)]),
+                        Spec = error_spec(severity_error, phase_oisu_check,
+                            [Msg]),
+                        !:Specs = [Spec | !.Specs]
+                    ),
+                    RestArgNum = ArgNum + 1,
+                    RestTypesModes = TypesModes
+                ;
+                    ThisKind = oisu_mutator,
+                    (
+                        TypesModes = [NextTypeMode | TailTypesModes],
+                        NextTypeMode = NextType - NextMode,
+                        NextType = Type
+                    ->
+                        ( mode_is_input(ModuleInfo, Mode) ->
+                            true
+                        ;
+                            InPredDesc = describe_one_pred_info_name(
+                                should_not_module_qualify, PredInfo),
+                            InPieces = [words("The"), nth_fixed(ArgNum),
+                                words("argument of")] ++ InPredDesc ++
+                                [words("should be the input of the mutator"),
+                                words("of its OISU type,"),
+                                words("but its mode is not input."), nl],
+                            pred_info_get_context(PredInfo, InContext),
+                            InMsg = simple_msg(InContext, [always(InPieces)]),
+                            InSpec = error_spec(severity_error,
+                                phase_oisu_check, [InMsg]),
+                            !:Specs = [InSpec | !.Specs]
+                        ),
+                        ( mode_is_output(ModuleInfo, NextMode) ->
+                            true
+                        ;
+                            OutPredDesc = describe_one_pred_info_name(
+                                should_not_module_qualify, PredInfo),
+                            OutPieces = [words("The"), nth_fixed(ArgNum + 1),
+                                words("argument of")] ++ OutPredDesc ++
+                                [words("should be the output of the mutator"),
+                                words("of its OISU type,"),
+                                words("but its mode is not output."), nl],
+                            pred_info_get_context(PredInfo, OutContext),
+                            OutMsg = simple_msg(OutContext,
+                                [always(OutPieces)]),
+                            OutSpec = error_spec(severity_error,
+                                phase_oisu_check, [OutMsg]),
+                            !:Specs = [OutSpec | !.Specs]
+                        ),
+                        RestArgNum = ArgNum + 2,
+                        RestTypesModes = TailTypesModes
+                    ;
+                        PredDesc = describe_one_pred_info_name(
+                            should_not_module_qualify, PredInfo),
+                        Pieces = [words("Since the"), nth_fixed(ArgNum),
+                            words("argument of")] ++ PredDesc ++
+                            [words("is a mutator of its OISU type,"),
+                            words("it should be followed by"),
+                            words("another argument of the same type."), nl],
+                        pred_info_get_context(PredInfo, Context),
+                        Msg = simple_msg(Context, [always(Pieces)]),
+                        Spec = error_spec(severity_error, phase_oisu_check,
+                            [Msg]),
+                        !:Specs = [Spec | !.Specs],
+                        RestArgNum = ArgNum + 1,
+                        RestTypesModes = TypesModes
+                    )
+                ;
+                    ThisKind = oisu_destructor,
+                    ( mode_is_input(ModuleInfo, Mode) ->
+                        true
+                    ;
+                        PredDesc = describe_one_pred_info_name(
+                            should_not_module_qualify, PredInfo),
+                        Pieces = [words("The"), nth_fixed(ArgNum),
+                            words("argument of")] ++ PredDesc ++
+                            [words("should be a destructor of its OISU type,"),
+                            words("but its mode is not input."), nl],
+                        pred_info_get_context(PredInfo, Context),
+                        Msg = simple_msg(Context, [always(Pieces)]),
+                        Spec = error_spec(severity_error, phase_oisu_check,
+                            [Msg]),
+                        !:Specs = [Spec | !.Specs]
+                    ),
+                    RestArgNum = ArgNum + 1,
+                    RestTypesModes = TypesModes
+                )
+            ),
+            check_arg_oisu_types(ModuleInfo, PredInfo, KindFors, OISUTypeCtors,
+                RestArgNum, !.HandledOISUTypeCtors, RestTypesModes, !Specs)
+        ;
+            PredDesc = describe_one_pred_info_name(should_not_module_qualify,
+                PredInfo),
+            Pieces = [words("The"), nth_fixed(ArgNum), words("argument of")] ++
+                PredDesc ++ [words("is an OISU type"),
+                words("but it is not listed in that type's OISU pragma."), nl],
+            pred_info_get_context(PredInfo, Context),
+            Msg = simple_msg(Context, [always(Pieces)]),
+            Spec = error_spec(severity_error, phase_oisu_check, [Msg]),
+            !:Specs = [Spec | !.Specs],
+            check_arg_oisu_types(ModuleInfo, PredInfo, KindFors, OISUTypeCtors,
+                ArgNum + 1, !.HandledOISUTypeCtors, TypesModes, !Specs)
+        )
+    ;
+        check_arg_oisu_types(ModuleInfo, PredInfo, KindFors, OISUTypeCtors,
+            ArgNum + 1, !.HandledOISUTypeCtors, TypesModes, !Specs)
+    ).
+check_arg_oisu_types(_ModuleInfo, PredInfo, KindFors, _OISUTypeCtors,
+        _ArgNum, !.HandledOISUTypeCtors, [], !Specs) :-
+    find_unhandled_oisu_kind_fors(KindFors, !.HandledOISUTypeCtors,
+        UnhandledKindFors),
+    (
+        UnhandledKindFors = []
+    ;
+        UnhandledKindFors = [HeadUnhandledKindFor | TailUnhandledKindFors],
+        describe_unhandled_kind_fors(HeadUnhandledKindFor,
+            TailUnhandledKindFors, UnhandledPieces),
+        PredDesc = describe_one_pred_info_name(should_not_module_qualify,
+            PredInfo),
+        Pieces = PredDesc ++ [words("is declared to handle"),
+            words("the following OISU types, but it does not:"),
+            nl_indent_delta(1)] ++ UnhandledPieces,
+        pred_info_get_context(PredInfo, Context),
+        Msg = simple_msg(Context, [always(Pieces)]),
+        Spec = error_spec(severity_error, phase_oisu_check, [Msg]),
+        !:Specs = [Spec | !.Specs]
+    ).
+
+:- pred find_kind_for_oisu_type(list(oisu_pred_kind_for)::in, type_ctor::in,
+    oisu_pred_kind::out) is semidet.
+
+find_kind_for_oisu_type([KindFor | KindFors], TypeCtor, Kind) :-
+    (
+        (
+            KindFor = oisu_creator_for(TypeCtor),
+            KindPrime = oisu_creator
+        ;
+            KindFor = oisu_mutator_for(TypeCtor),
+            KindPrime = oisu_mutator
+        ;
+            KindFor = oisu_destructor_for(TypeCtor),
+            KindPrime = oisu_destructor
+        )
+    ->
+        Kind = KindPrime
+    ;
+        find_kind_for_oisu_type(KindFors, TypeCtor, Kind)
+    ).
+
+:- pred find_unhandled_oisu_kind_fors(list(oisu_pred_kind_for)::in,
+    list(type_ctor)::in, list(oisu_pred_kind_for)::out) is det.
+
+find_unhandled_oisu_kind_fors([], _, []).
+find_unhandled_oisu_kind_fors([KindFor | KindFors], HandledOISUTypeCtors,
+        UnhandledKindFors) :-
+    find_unhandled_oisu_kind_fors(KindFors, HandledOISUTypeCtors,
+        UnhandledKindForsTail),
+    ( KindFor = oisu_creator_for(TypeCtor)
+    ; KindFor = oisu_mutator_for(TypeCtor)
+    ; KindFor = oisu_destructor_for(TypeCtor)
+    ),
+    ( list.member(TypeCtor, HandledOISUTypeCtors) ->
+        UnhandledKindFors = UnhandledKindForsTail
+    ;
+        UnhandledKindFors = [KindFor | UnhandledKindForsTail]
+    ).
+
+:- pred describe_unhandled_kind_fors(
+    oisu_pred_kind_for::in, list(oisu_pred_kind_for)::in,
+    list(format_component)::out) is det.
+
+describe_unhandled_kind_fors(HeadKindFor, TailKindFors, Pieces) :-
+    ( HeadKindFor = oisu_creator_for(HeadTypeCtor), HeadKind = "creator"
+    ; HeadKindFor = oisu_mutator_for(HeadTypeCtor), HeadKind = "mutator"
+    ; HeadKindFor = oisu_destructor_for(HeadTypeCtor), HeadKind = "destructor"
+    ),
+    HeadTypeCtor = type_ctor(HeadTypeSymName, HeadTypeArity),
+    HeadPieces0 = [sym_name_and_arity(HeadTypeSymName / HeadTypeArity),
+        fixed("(as " ++ HeadKind ++ ")")],
+    (
+        TailKindFors = [],
+        HeadPieces = HeadPieces0 ++ [suffix("."), nl],
+        Pieces = HeadPieces
+    ;
+        TailKindFors = [HeadTailKindFor | TailTailKindFors],
+        HeadPieces = HeadPieces0 ++ [suffix(","), nl],
+        describe_unhandled_kind_fors(HeadTailKindFor, TailTailKindFors,
+            TailPieces),
+        Pieces = HeadPieces ++ TailPieces
+    ).
+
+%-----------------------------------------------------------------------------%
+
+:- pred check_args_have_no_oisu_types(pred_info::in, list(type_ctor)::in,
+    list(mer_type)::in, list(error_spec)::in, list(error_spec)::out) is det.
+
+check_args_have_no_oisu_types(_PredInfo, _OISUTypeCtors, [], !Specs).
+check_args_have_no_oisu_types(PredInfo, OISUTypeCtors, [Type | Types],
+        !Specs) :-
+    (
+        type_to_ctor_and_args(Type, TypeCtor, ArgTypes),
+        ArgTypes = [],
+        list.member(TypeCtor, OISUTypeCtors)
+    ->
+        PredDesc = describe_one_pred_info_name(should_not_module_qualify,
+            PredInfo),
+        TypeCtor = type_ctor(TypeName, TypeArity),
+        ProcsPieces = PredDesc ++ [words("is not mentioned"),
+            words("in the"), quote("pragma oisu"), words("declaration"),
+            words("as a predicate that handles values of the type"),
+            sym_name_and_arity(TypeName / TypeArity), nl],
+        pred_info_get_context(PredInfo, Context),
+        ProcsMsg = simple_msg(Context, [always(ProcsPieces)]),
+        ProcsSpec = error_spec(severity_error, phase_oisu_check,
+            [ProcsMsg]),
+        !:Specs = [ProcsSpec | !.Specs]
+    ;
+        true
+    ),
+    check_args_have_no_oisu_types(PredInfo, OISUTypeCtors, Types, !Specs).
+
+%-----------------------------------------------------------------------------%
+:- end_module check_hlds.oisu_check.
+%-----------------------------------------------------------------------------%
Index: compiler/prog_io_pragma.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/prog_io_pragma.m,v
retrieving revision 1.153
diff -u -b -r1.153 prog_io_pragma.m
--- compiler/prog_io_pragma.m	10 Sep 2012 13:33:08 -0000	1.153
+++ compiler/prog_io_pragma.m	7 Oct 2012 11:13:27 -0000
@@ -257,7 +257,7 @@
             "type", MakePragma, PragmaTerms, ErrorTerm,
             VarSet, Context, SeqNum, MaybeItem)
     ;
-        PragmaName = "ousi",
+        PragmaName = "oisu",
         parse_oisu_pragma(ModuleName, PragmaTerms, ErrorTerm,
             VarSet, Context, SeqNum, MaybeItem)
     ;
@@ -2396,7 +2396,7 @@
             MutatorsTerm, MaybeMutatorsNamesArities),
         (
             MaybeDestructorsTerm = yes(DestructorsTerm2),
-            parse_oisu_preds_term(ModuleName, VarSet, "third", "mutators",
+            parse_oisu_preds_term(ModuleName, VarSet, "fourth", "destructors",
                 DestructorsTerm2, MaybeDestructorsNamesArities)
         ;
             MaybeDestructorsTerm = no,
Index: compiler/stratify.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/stratify.m,v
retrieving revision 1.82
diff -u -b -r1.82 stratify.m
--- compiler/stratify.m	8 Jun 2012 15:37:01 -0000	1.82
+++ compiler/stratify.m	7 Oct 2012 11:13:28 -0000
@@ -38,13 +38,13 @@
 
 :- import_module list.
 
-    % Perform stratification analysis, for the given module. If the
+    % Perform stratification analysis for the given module. If the
     % "warn-non-stratification" option is set, this predicate will check
     % the entire module for stratification, otherwise it will only check
     % the predicates in the stratified_preds set of the module_info structure.
     %
-:- pred check_stratification(module_info::in, module_info::out,
-    list(error_spec)::in, list(error_spec)::out) is det.
+:- pred check_module_for_stratification(module_info::in, module_info::out,
+    list(error_spec)::out) is det.
 
 %-----------------------------------------------------------------------------%
 %-----------------------------------------------------------------------------%
@@ -75,7 +75,7 @@
 :- import_module set.
 :- import_module string.
 
-check_stratification(!ModuleInfo, !Specs) :-
+check_module_for_stratification(!ModuleInfo, Specs) :-
     module_info_ensure_dependency_info(!ModuleInfo),
     module_info_dependency_info(!.ModuleInfo, DepInfo),
 
@@ -86,7 +86,7 @@
     globals.lookup_bool_option(Globals, warn_non_stratification, Warn),
     module_info_get_stratified_preds(!.ModuleInfo, StratifiedPreds),
     first_order_check_sccs(FOSCCs, StratifiedPreds, Warn, !.ModuleInfo,
-        !Specs).
+        [], Specs).
 
     % The following code was used for the second pass of this module but
     % as that pass is disabled, so is this code. The higher order code
@@ -126,10 +126,8 @@
 first_order_check_sccs([], _, _, _, !Specs).
 first_order_check_sccs([SCCl - SCCs | Rest], StratifiedPreds, Warn0,
         ModuleInfo, !Specs) :-
-    (
         set.intersect(SCCs, StratifiedPreds, Intersection),
-        set.is_empty(Intersection)
-    ->
+    ( set.is_empty(Intersection) ->
         Warn = Warn0
     ;
         Warn = yes
cvs diff: Diffing compiler/notes
cvs diff: Diffing deep_profiler
cvs diff: Diffing deep_profiler/notes
cvs diff: Diffing doc
cvs diff: Diffing extras
cvs diff: Diffing extras/base64
cvs diff: Diffing extras/cgi
cvs diff: Diffing extras/complex_numbers
cvs diff: Diffing extras/complex_numbers/samples
cvs diff: Diffing extras/complex_numbers/tests
cvs diff: Diffing extras/curs
cvs diff: Diffing extras/curs/samples
cvs diff: Diffing extras/curses
cvs diff: Diffing extras/curses/sample
cvs diff: Diffing extras/dynamic_linking
cvs diff: Diffing extras/error
cvs diff: Diffing extras/fixed
cvs diff: Diffing extras/gator
cvs diff: Diffing extras/gator/generations
cvs diff: Diffing extras/gator/generations/1
cvs diff: Diffing extras/graphics
cvs diff: Diffing extras/graphics/easyx
cvs diff: Diffing extras/graphics/easyx/samples
cvs diff: Diffing extras/graphics/mercury_allegro
cvs diff: Diffing extras/graphics/mercury_allegro/examples
cvs diff: Diffing extras/graphics/mercury_allegro/samples
cvs diff: Diffing extras/graphics/mercury_allegro/samples/demo
cvs diff: Diffing extras/graphics/mercury_allegro/samples/mandel
cvs diff: Diffing extras/graphics/mercury_allegro/samples/pendulum2
cvs diff: Diffing extras/graphics/mercury_allegro/samples/speed
cvs diff: Diffing extras/graphics/mercury_cairo
cvs diff: Diffing extras/graphics/mercury_cairo/samples
cvs diff: Diffing extras/graphics/mercury_cairo/samples/data
cvs diff: Diffing extras/graphics/mercury_cairo/tutorial
cvs diff: Diffing extras/graphics/mercury_glfw
cvs diff: Diffing extras/graphics/mercury_glfw/samples
cvs diff: Diffing extras/graphics/mercury_glut
cvs diff: Diffing extras/graphics/mercury_opengl
cvs diff: Diffing extras/graphics/mercury_tcltk
cvs diff: Diffing extras/graphics/samples
cvs diff: Diffing extras/graphics/samples/calc
cvs diff: Diffing extras/graphics/samples/gears
cvs diff: Diffing extras/graphics/samples/maze
cvs diff: Diffing extras/graphics/samples/pent
cvs diff: Diffing extras/lazy_evaluation
cvs diff: Diffing extras/lex
cvs diff: Diffing extras/lex/samples
cvs diff: Diffing extras/lex/tests
cvs diff: Diffing extras/log4m
cvs diff: Diffing extras/logged_output
cvs diff: Diffing extras/monte
cvs diff: Diffing extras/moose
cvs diff: Diffing extras/moose/samples
cvs diff: Diffing extras/moose/tests
cvs diff: Diffing extras/mopenssl
cvs diff: Diffing extras/morphine
cvs diff: Diffing extras/morphine/non-regression-tests
cvs diff: Diffing extras/morphine/scripts
cvs diff: Diffing extras/morphine/source
cvs diff: Diffing extras/net
cvs diff: Diffing extras/odbc
cvs diff: Diffing extras/posix
cvs diff: Diffing extras/posix/samples
cvs diff: Diffing extras/quickcheck
cvs diff: Diffing extras/quickcheck/tutes
cvs diff: Diffing extras/references
cvs diff: Diffing extras/references/samples
cvs diff: Diffing extras/references/tests
cvs diff: Diffing extras/solver_types
cvs diff: Diffing extras/solver_types/library
cvs diff: Diffing extras/trailed_update
cvs diff: Diffing extras/trailed_update/samples
cvs diff: Diffing extras/trailed_update/tests
cvs diff: Diffing extras/windows_installer_generator
cvs diff: Diffing extras/windows_installer_generator/sample
cvs diff: Diffing extras/windows_installer_generator/sample/images
cvs diff: Diffing extras/xml
cvs diff: Diffing extras/xml/samples
cvs diff: Diffing extras/xml_stylesheets
cvs diff: Diffing java
cvs diff: Diffing java/runtime
cvs diff: Diffing library
cvs diff: Diffing m4
cvs diff: Diffing mdbcomp
cvs diff: Diffing profiler
cvs diff: Diffing robdd
cvs diff: Diffing runtime
cvs diff: Diffing runtime/GETOPT
cvs diff: Diffing runtime/machdeps
cvs diff: Diffing runtime/notes
cvs diff: Diffing samples
cvs diff: Diffing samples/appengine
cvs diff: Diffing samples/appengine/war
cvs diff: Diffing samples/appengine/war/WEB-INF
cvs diff: Diffing samples/c_interface
cvs diff: Diffing samples/c_interface/c_calls_mercury
cvs diff: Diffing samples/c_interface/cplusplus_calls_mercury
cvs diff: Diffing samples/c_interface/mercury_calls_c
cvs diff: Diffing samples/c_interface/mercury_calls_cplusplus
cvs diff: Diffing samples/c_interface/mercury_calls_fortran
cvs diff: Diffing samples/c_interface/simpler_c_calls_mercury
cvs diff: Diffing samples/c_interface/simpler_cplusplus_calls_mercury
cvs diff: Diffing samples/c_interface/standalone_c
cvs diff: Diffing samples/concurrency
cvs diff: Diffing samples/concurrency/dining_philosophers
cvs diff: Diffing samples/concurrency/midimon
cvs diff: Diffing samples/diff
cvs diff: Diffing samples/java_interface
cvs diff: Diffing samples/java_interface/java_calls_mercury
cvs diff: Diffing samples/java_interface/mercury_calls_java
cvs diff: Diffing samples/lazy_list
cvs diff: Diffing samples/muz
cvs diff: Diffing samples/rot13
cvs diff: Diffing samples/solutions
cvs diff: Diffing samples/solver_types
cvs diff: Diffing samples/tests
cvs diff: Diffing samples/tests/c_interface
cvs diff: Diffing samples/tests/c_interface/c_calls_mercury
cvs diff: Diffing samples/tests/c_interface/cplusplus_calls_mercury
cvs diff: Diffing samples/tests/c_interface/mercury_calls_c
cvs diff: Diffing samples/tests/c_interface/mercury_calls_cplusplus
cvs diff: Diffing samples/tests/c_interface/mercury_calls_fortran
cvs diff: Diffing samples/tests/c_interface/simpler_c_calls_mercury
cvs diff: Diffing samples/tests/c_interface/simpler_cplusplus_calls_mercury
cvs diff: Diffing samples/tests/diff
cvs diff: Diffing samples/tests/muz
cvs diff: Diffing samples/tests/rot13
cvs diff: Diffing samples/tests/solutions
cvs diff: Diffing samples/tests/toplevel
cvs diff: Diffing scripts
cvs diff: Diffing slice
cvs diff: Diffing ssdb
cvs diff: Diffing tests
cvs diff: Diffing tests/analysis
cvs diff: Diffing tests/analysis/ctgc
cvs diff: Diffing tests/analysis/excp
cvs diff: Diffing tests/analysis/ext
cvs diff: Diffing tests/analysis/sharing
cvs diff: Diffing tests/analysis/table
cvs diff: Diffing tests/analysis/trail
cvs diff: Diffing tests/analysis/unused_args
cvs diff: Diffing tests/benchmarks
cvs diff: Diffing tests/debugger
cvs diff: Diffing tests/debugger/declarative
cvs diff: Diffing tests/dppd
cvs diff: Diffing tests/feedback
cvs diff: Diffing tests/feedback/mandelbrot
cvs diff: Diffing tests/feedback/mmc
cvs diff: Diffing tests/general
cvs diff: Diffing tests/general/accumulator
cvs diff: Diffing tests/general/string_format
cvs diff: Diffing tests/general/structure_reuse
cvs diff: Diffing tests/grade_subdirs
cvs diff: Diffing tests/hard_coded
Index: tests/hard_coded/Mmakefile
===================================================================
RCS file: /home/mercury/mercury1/repository/tests/hard_coded/Mmakefile,v
retrieving revision 1.431
diff -u -b -r1.431 Mmakefile
--- tests/hard_coded/Mmakefile	7 Aug 2012 01:22:57 -0000	1.431
+++ tests/hard_coded/Mmakefile	7 Oct 2012 11:13:30 -0000
@@ -206,6 +206,7 @@
 	nondet_ctrl_vn \
 	nondet_lambda \
 	nullary_ho_func \
+	oisu_check_main \
 	one_member \
 	opt_dup_bug \
 	opt_format \
Index: tests/hard_coded/oisu_check_db.m
===================================================================
RCS file: tests/hard_coded/oisu_check_db.m
diff -N tests/hard_coded/oisu_check_db.m
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ tests/hard_coded/oisu_check_db.m	7 Oct 2012 11:13:30 -0000
@@ -0,0 +1,44 @@
+% vim: ts=4 sw=4 et ft=mercury
+
+:- module oisu_check_db.
+:- interface.
+
+:- import_module bool.
+
+:- type db.
+
+:- pragma oisu(db/0,
+        creators([create_db1/1, create_db2/2]),
+        mutators([mutate_db1/3, mutate_db2/3]),
+        destructors([destroy_db/3])
+    ).
+
+:- pred create_db1(db::out) is det.
+:- pred create_db2(int::in, db::out) is det.
+
+:- pred mutate_db1(bool::in, db::in, db::out) is det.
+:- pred mutate_db2(int::in, db::in, db::out) is det.
+
+:- pred destroy_db(db::in, bool::out, int::out) is det.
+
+:- implementation.
+
+:- type db
+	--->	db(bool, int).
+
+create_db1(DB) :-
+	DB = db(no, 0).
+
+create_db2(N, DB) :-
+	DB = db(no, N).
+
+mutate_db1(B, !DB) :-
+	!.DB = db(_, N),
+	!:DB = db(B, N).
+
+mutate_db2(N, !DB) :-
+	!.DB = db(B, _),
+	!:DB = db(B, N).
+
+destroy_db(DB, B, N) :-
+	DB = db(B, N).
Index: tests/hard_coded/oisu_check_main.exp
===================================================================
RCS file: tests/hard_coded/oisu_check_main.exp
diff -N tests/hard_coded/oisu_check_main.exp
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ tests/hard_coded/oisu_check_main.exp	7 Oct 2012 11:13:30 -0000
@@ -0,0 +1,2 @@
+yes - 2
+yes - 4
Index: tests/hard_coded/oisu_check_main.m
===================================================================
RCS file: tests/hard_coded/oisu_check_main.m
diff -N tests/hard_coded/oisu_check_main.m
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ tests/hard_coded/oisu_check_main.m	7 Oct 2012 11:13:30 -0000
@@ -0,0 +1,31 @@
+% vim: ts=4 sw=4 et ft=mercury
+
+:- module oisu_check_main.
+:- interface.
+
+:- import_module io.
+
+:- pred main(io::di, io::uo) is det.
+
+:- implementation.
+
+:- import_module oisu_check_db.
+:- import_module bool.
+:- import_module pair.
+
+main(!IO) :-
+    some [!DBA, !DBB] (
+        create_db1(!:DBA),
+        mutate_db1(yes, !DBA),
+        mutate_db2(2, !DBA),
+        destroy_db(!.DBA, BA, NA),
+
+        create_db2(3, !:DBB),
+        mutate_db1(yes, !DBB),
+        mutate_db2(4, !DBB),
+        destroy_db(!.DBB, BB, NB)
+    ),
+    io.write(BA - NA, !IO),
+    io.nl(!IO),
+    io.write(BB - NB, !IO),
+    io.nl(!IO).
cvs diff: Diffing tests/hard_coded/exceptions
cvs diff: Diffing tests/hard_coded/purity
cvs diff: Diffing tests/hard_coded/sub-modules
cvs diff: Diffing tests/hard_coded/typeclasses
cvs diff: Diffing tests/invalid
Index: tests/invalid/Mmakefile
===================================================================
RCS file: /home/mercury/mercury1/repository/tests/invalid/Mmakefile,v
retrieving revision 1.250
diff -u -b -r1.250 Mmakefile
--- tests/invalid/Mmakefile	5 Jun 2012 15:14:28 -0000	1.250
+++ tests/invalid/Mmakefile	7 Oct 2012 11:13:31 -0000
@@ -165,6 +165,8 @@
 	null_char \
 	nullary_ho_func_error \
 	occurs \
+	oisu_check_add_pragma_errors \
+	oisu_check_semantic_errors \
 	one_member \
 	overloading \
 	polymorphic_unification \
Index: tests/invalid/oisu_check_add_pragma_errors.err_exp
===================================================================
RCS file: tests/invalid/oisu_check_add_pragma_errors.err_exp
diff -N tests/invalid/oisu_check_add_pragma_errors.err_exp
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ tests/invalid/oisu_check_add_pragma_errors.err_exp	7 Oct 2012 11:13:31 -0000
@@ -0,0 +1,19 @@
+oisu_check_add_pragma_errors.m:014: Duplicate `pragma oisu' declaration for
+oisu_check_add_pragma_errors.m:014:   `oisu_check_add_pragma_errors.foo'/0.
+oisu_check_add_pragma_errors.m:020: In pragma oisu:
+oisu_check_add_pragma_errors.m:020:   error: undefined type
+oisu_check_add_pragma_errors.m:020:   `oisu_check_add_pragma_errors.quux'/0.
+oisu_check_add_pragma_errors.m:028: `pragma oisu' declarations must always be
+oisu_check_add_pragma_errors.m:028:   exported.
+oisu_check_add_pragma_errors.m:028: In the first destructor predicate
+oisu_check_add_pragma_errors.m:028:   specification within the `pragma oisu'
+oisu_check_add_pragma_errors.m:028:   declaration for
+oisu_check_add_pragma_errors.m:028:   `oisu_check_add_pragma_errors.bar'/0:
+oisu_check_add_pragma_errors.m:028:   error: predicate
+oisu_check_add_pragma_errors.m:028:   `oisu_check_add_pragma_errors.destroy_bar'/3
+oisu_check_add_pragma_errors.m:028:   has the wrong arity. Actual arity is 3,
+oisu_check_add_pragma_errors.m:028:   expected arity is 2.
+oisu_check_add_pragma_errors.m:028: The type in a `pragma oisu' declaration
+oisu_check_add_pragma_errors.m:028:   must always be abstract exported.
+oisu_check_add_pragma_errors.m:034: `pragma oisu' declarations must always be
+oisu_check_add_pragma_errors.m:034:   exported.
Index: tests/invalid/oisu_check_add_pragma_errors.m
===================================================================
RCS file: tests/invalid/oisu_check_add_pragma_errors.m
diff -N tests/invalid/oisu_check_add_pragma_errors.m
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ tests/invalid/oisu_check_add_pragma_errors.m	7 Oct 2012 11:13:31 -0000
@@ -0,0 +1,102 @@
+% vim: ts=4 sw=4 et ft=mercury
+
+:- module oisu_check_add_pragma_errors.
+:- interface.
+
+:- type foo.
+:- type baz.
+
+:- pragma oisu(foo/0,
+        creators([create_foo/1]),
+        mutators([mutate_foo/3])
+    ).
+
+:- pragma oisu(foo/0,
+        creators([create_foo/1]),
+        mutators([mutate_foo/3]),
+        destructors([destroy_foo/3])
+    ).
+
+:- pragma oisu(quux/0,
+        creators([create_quux/1]),
+        mutators([mutate_quux/3]),
+        destructors([destroy_quux/2])
+    ).
+
+:- implementation.
+
+:- pragma oisu(bar/0,
+        creators([create_bar/1]),
+        mutators([mutate_bar/3]),
+        destructors([destroy_bar/3])
+    ).
+
+:- pragma oisu(baz/0,
+        creators([create_baz/1]),
+        mutators([mutate_baz/3])
+    ).
+
+:- type foo
+	--->	foo(int, int).
+
+:- type bar
+    --->    bar(int).
+
+:- type baz
+    --->    baz(float).
+
+:- pred create_foo(foo::out) is det.
+:- pred mutate_foo(int::in, foo::in, foo::out) is det.
+:- pred destroy_foo(foo::in, int::out, int::out) is det.
+
+create_foo(Foo) :-
+	Foo = foo(0, 0).
+
+mutate_foo(N, Foo0, Foo) :-
+    Foo0 = foo(_, _),
+    Foo = foo(N, N).
+
+destroy_foo(Foo, A, B) :-
+	Foo = foo(A, B).
+
+:- pred create_bar(bar::out) is det.
+:- pred mutate_bar(int::in, bar::in, bar::out) is det.
+:- pred destroy_bar(bar::in, int::out) is det.
+
+create_bar(Bar) :-
+	Bar = bar(0).
+
+mutate_bar(N, Bar0, Bar) :-
+    Bar0 = bar(_),
+    Bar = bar(N).
+
+destroy_bar(Bar, A) :-
+	Bar = bar(A).
+
+:- pred create_baz(baz::out) is det.
+:- pred mutate_baz(float::in, baz::in, baz::out) is det.
+:- pred destroy_baz(baz::in, float::out) is det.
+
+create_baz(Baz) :-
+	Baz = baz(0).
+
+mutate_baz(N, Baz0, Baz) :-
+    Baz0 = baz(_),
+    Baz = baz(N).
+
+destroy_baz(Baz, A) :-
+	Baz = baz(A).
+
+:- pred create_quux(baz::out) is det.
+:- pred mutate_quux(float::in, baz::in, baz::out) is det.
+:- pred destroy_quux(baz::in, float::out) is det.
+
+create_quux(Baz) :-
+	Baz = baz(0).
+
+mutate_quux(N, Baz0, Baz) :-
+    Baz0 = baz(_),
+    Baz = baz(N).
+
+destroy_quux(Baz, A) :-
+	Baz = baz(A).
Index: tests/invalid/oisu_check_semantic_errors.err_exp
===================================================================
RCS file: tests/invalid/oisu_check_semantic_errors.err_exp
diff -N tests/invalid/oisu_check_semantic_errors.err_exp
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ tests/invalid/oisu_check_semantic_errors.err_exp	7 Oct 2012 11:13:31 -0000
@@ -0,0 +1,48 @@
+oisu_check_semantic_errors.m:026: The first argument of predicate
+oisu_check_semantic_errors.m:026:   `create_foo2'/1 should be a creator of its
+oisu_check_semantic_errors.m:026:   OISU type, but its mode is not output.
+oisu_check_semantic_errors.m:027: The second argument of predicate
+oisu_check_semantic_errors.m:027:   `create_foo3'/2 handles a previous handled
+oisu_check_semantic_errors.m:027:   OISU type.
+oisu_check_semantic_errors.m:029: Since the first argument of predicate
+oisu_check_semantic_errors.m:029:   `mutate_foo1'/3 is a mutator of its OISU
+oisu_check_semantic_errors.m:029:   type, it should be followed by another
+oisu_check_semantic_errors.m:029:   argument of the same type.
+oisu_check_semantic_errors.m:029: The third argument of predicate
+oisu_check_semantic_errors.m:029:   `mutate_foo1'/3 handles a previous handled
+oisu_check_semantic_errors.m:029:   OISU type.
+oisu_check_semantic_errors.m:030: The second argument of predicate
+oisu_check_semantic_errors.m:030:   `mutate_foo2'/3 should be the input of the
+oisu_check_semantic_errors.m:030:   mutator of its OISU type, but its mode is
+oisu_check_semantic_errors.m:030:   not input.
+oisu_check_semantic_errors.m:030: The third argument of predicate
+oisu_check_semantic_errors.m:030:   `mutate_foo2'/3 should be the output of the
+oisu_check_semantic_errors.m:030:   mutator of its OISU type, but its mode is
+oisu_check_semantic_errors.m:030:   not output.
+oisu_check_semantic_errors.m:032: predicate `destroy_foo1'/3 is declared to
+oisu_check_semantic_errors.m:032:   handle the following OISU types, but it
+oisu_check_semantic_errors.m:032:   does not:
+oisu_check_semantic_errors.m:032:     `oisu_check_semantic_errors.bar'/0
+oisu_check_semantic_errors.m:032:     (as destructor).
+oisu_check_semantic_errors.m:033: The first argument of predicate
+oisu_check_semantic_errors.m:033:   `destroy_foo2'/3 should be a destructor of
+oisu_check_semantic_errors.m:033:   its OISU type, but its mode is not input.
+oisu_check_semantic_errors.m:034: The second argument of predicate
+oisu_check_semantic_errors.m:034:   `destroy_foo3'/4 handles a previous handled
+oisu_check_semantic_errors.m:034:   OISU type.
+oisu_check_semantic_errors.m:035: predicate `destroy_foo4'/3 is mentioned in a
+oisu_check_semantic_errors.m:035:   `pragma oisu' declaration, so it should
+oisu_check_semantic_errors.m:035:   have exactly one procedure.
+oisu_check_semantic_errors.m:039: predicate `create_bar1'/2 is declared to
+oisu_check_semantic_errors.m:039:   handle the following OISU types, but it
+oisu_check_semantic_errors.m:039:   does not:
+oisu_check_semantic_errors.m:039:     `oisu_check_semantic_errors.foo'/0
+oisu_check_semantic_errors.m:039:     (as mutator).
+oisu_check_semantic_errors.m:043: predicate `destroy_bar1'/3 is declared to
+oisu_check_semantic_errors.m:043:   handle the following OISU types, but it
+oisu_check_semantic_errors.m:043:   does not:
+oisu_check_semantic_errors.m:043:     `oisu_check_semantic_errors.foo'/0
+oisu_check_semantic_errors.m:043:     (as destructor).
+oisu_check_semantic_errors.m:045: The second argument of predicate
+oisu_check_semantic_errors.m:045:   `create_foobar1'/3 is an OISU type but it
+oisu_check_semantic_errors.m:045:   is not listed in that type's OISU pragma.
Index: tests/invalid/oisu_check_semantic_errors.m
===================================================================
RCS file: tests/invalid/oisu_check_semantic_errors.m
diff -N tests/invalid/oisu_check_semantic_errors.m
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ tests/invalid/oisu_check_semantic_errors.m	7 Oct 2012 11:13:31 -0000
@@ -0,0 +1,108 @@
+% vim: ts=4 sw=4 et ft=mercury
+
+:- module oisu_check_semantic_errors.
+:- interface.
+
+:- import_module bool.
+
+:- type foo.
+:- type bar.
+
+:- pragma oisu(foo/0,
+        creators([create_foo1/2, create_foo2/1, create_foo3/2, destroy_foo4/3]),
+        mutators([mutate_foo1/3, mutate_foo2/3, create_bar1/2,
+            mutate_foobar1/5]),
+        destructors([destroy_foo1/3, destroy_foo2/3, destroy_foo3/4,
+            destroy_bar1/3])
+    ).
+
+:- pragma oisu(bar/0,
+        creators([create_bar1/2, create_foobar1/3]),
+        mutators([mutate_bar1/3, mutate_foobar1/5]),
+        destructors([destroy_bar1/3, destroy_foo1/3]) 
+    ).
+
+:- pred create_foo1(int::in, foo::out) is semidet.
+:- pred create_foo2(foo::in) is det.
+:- pred create_foo3(foo::out, foo::in) is det.
+
+:- pred mutate_foo1(foo::in, bool::in, foo::out) is det.
+:- pred mutate_foo2(int::in, foo::out, foo::in) is det.
+
+:- pred destroy_foo1(foo::in, bool::out, int::out) is semidet.
+:- pred destroy_foo2(foo::out, bool::in, int::in) is det.
+:- pred destroy_foo3(foo::in, foo::out, bool::out, int::out) is det.
+:- pred destroy_foo4(foo, bool, int).
+:- mode destroy_foo4(in, out, out) is det.
+:- mode destroy_foo4(out, in, in) is det.
+
+:- pred create_bar1(int::in, bar::out) is semidet.
+
+:- pred mutate_bar1(bar::in, bar::out, int::in) is det.
+
+:- pred destroy_bar1(bar::in, int::out, int::out) is det.
+
+:- pred create_foobar1(int::in, foo::out, bar::out) is det.
+
+:- pred mutate_foobar1(int::in, foo::in, foo::out, bar::in, bar::out) is det.
+
+:- implementation.
+
+:- import_module int.
+
+:- type foo
+	--->	foo(bool, int).
+
+:- type bar
+	--->	bar(int, int).
+
+create_foo1(N, Foo) :-
+    N > 10,
+	Foo = foo(no, N).
+
+create_foo2(_Foo).
+
+create_foo3(Foo, Foo).
+
+mutate_foo1(Foo0, B, Foo) :-
+	Foo0 = foo(_, N),
+	Foo = foo(B, N).
+
+mutate_foo2(N, Foo, Foo0) :-
+	Foo0 = foo(B, _),
+	Foo = foo(B, N).
+
+destroy_foo1(Foo, B, N) :-
+	Foo = foo(B, N),
+    N > 10.
+
+destroy_foo2(Foo, B, N) :-
+	Foo = foo(B, N).
+
+destroy_foo3(Foo0, Foo, B, N) :-
+	Foo0 = foo(B, N),
+    Foo = Foo0.
+
+destroy_foo4(Foo, B, N) :-
+	Foo = foo(B, N).
+
+create_bar1(N, Bar) :-
+    N > 10,
+	Bar = bar(N, N).
+
+mutate_bar1(Bar0, Bar, N) :-
+    Bar0 = bar(_, M),
+	Bar = bar(N, M).
+
+destroy_bar1(Bar, N, M) :-
+	Bar = bar(N, M).
+
+create_foobar1(N, Foo, Bar) :-
+    Foo = foo(no, N),
+	Bar = bar(N, N).
+
+mutate_foobar1(N, Foo0, Foo, Bar0, Bar) :-
+    Foo0 = foo(B, _),
+    Foo = foo(B, N),
+	Bar0 = bar(_, M),
+	Bar = bar(N, M).
cvs diff: Diffing tests/invalid/purity
cvs diff: Diffing tests/misc_tests
cvs diff: Diffing tests/mmc_make
cvs diff: Diffing tests/mmc_make/lib
cvs diff: Diffing tests/par_conj
cvs diff: Diffing tests/recompilation
cvs diff: Diffing tests/stm
cvs diff: Diffing tests/stm/orig
cvs diff: Diffing tests/stm/orig/stm-compiler
cvs diff: Diffing tests/stm/orig/stm-compiler/test1
cvs diff: Diffing tests/stm/orig/stm-compiler/test10
cvs diff: Diffing tests/stm/orig/stm-compiler/test2
cvs diff: Diffing tests/stm/orig/stm-compiler/test3
cvs diff: Diffing tests/stm/orig/stm-compiler/test4
cvs diff: Diffing tests/stm/orig/stm-compiler/test5
cvs diff: Diffing tests/stm/orig/stm-compiler/test6
cvs diff: Diffing tests/stm/orig/stm-compiler/test7
cvs diff: Diffing tests/stm/orig/stm-compiler/test8
cvs diff: Diffing tests/stm/orig/stm-compiler/test9
cvs diff: Diffing tests/stm/orig/stm-compiler-par
cvs diff: Diffing tests/stm/orig/stm-compiler-par/bm1
cvs diff: Diffing tests/stm/orig/stm-compiler-par/bm2
cvs diff: Diffing tests/stm/orig/stm-compiler-par/stmqueue
cvs diff: Diffing tests/stm/orig/stm-compiler-par/test1
cvs diff: Diffing tests/stm/orig/stm-compiler-par/test10
cvs diff: Diffing tests/stm/orig/stm-compiler-par/test11
cvs diff: Diffing tests/stm/orig/stm-compiler-par/test2
cvs diff: Diffing tests/stm/orig/stm-compiler-par/test3
cvs diff: Diffing tests/stm/orig/stm-compiler-par/test4
cvs diff: Diffing tests/stm/orig/stm-compiler-par/test5
cvs diff: Diffing tests/stm/orig/stm-compiler-par/test6
cvs diff: Diffing tests/stm/orig/stm-compiler-par/test7
cvs diff: Diffing tests/stm/orig/stm-compiler-par/test8
cvs diff: Diffing tests/stm/orig/stm-compiler-par/test9
cvs diff: Diffing tests/stm/orig/stm-compiler-par-asm_fast
cvs diff: Diffing tests/stm/orig/stm-compiler-par-asm_fast/test1
cvs diff: Diffing tests/stm/orig/stm-compiler-par-asm_fast/test2
cvs diff: Diffing tests/stm/orig/stm-compiler-par-asm_fast/test3
cvs diff: Diffing tests/stm/orig/stm-compiler-par-asm_fast/test4
cvs diff: Diffing tests/stm/orig/stm-compiler-par-asm_fast/test5
cvs diff: Diffing tests/stm/orig/stm-compiler-par-asm_fast/test6
cvs diff: Diffing tests/stm/orig/stm-compiler-par-asm_fast/test7
cvs diff: Diffing tests/stm/orig/stm-compiler-par-asm_fast/test8
cvs diff: Diffing tests/stm/orig/stm-compiler-par-asm_fast/test9
cvs diff: Diffing tests/tabling
cvs diff: Diffing tests/term
cvs diff: Diffing tests/trailing
cvs diff: Diffing tests/valid
cvs diff: Diffing tests/warnings
cvs diff: Diffing tools
cvs diff: Diffing trace
cvs diff: Diffing util
cvs diff: Diffing vim
cvs diff: Diffing vim/after
cvs diff: Diffing vim/ftplugin
cvs diff: Diffing vim/syntax
--------------------------------------------------------------------------
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