[m-rev.] For review (needs committing): Cleanup samples/diff and samples/rot13

Jonathan Morgan jonmmorgan at gmail.com
Mon Apr 24 15:52:46 AEST 2006


Estimated hours taken: 3
Branches: main

samples/diff/*.m:
samples/rot13/*.m:
       Convert these modules to four-space indentation.

       Use state variables for threading the I/O state.

       Replace separate pred/mode declaration with predmode declarations.

       Replace __ with . as the module qualifier.

Index: samples/diff/diff.m
===================================================================
RCS file: /home/mercury1/repository/mercury/samples/diff/diff.m,v
retrieving revision 1.10
diff -u -r1.10 diff.m
--- samples/diff/diff.m	15 Sep 1998 04:54:16 -0000	1.10
+++ samples/diff/diff.m	24 Apr 2006 05:48:16 -0000
@@ -1,4 +1,6 @@
 %-----------------------------------------------------------------------------%
+% vim: ft=mercury ts=4 sw=4 et
+%-----------------------------------------------------------------------------%
 % Copyright (C) 1995-1998 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.
@@ -15,7 +17,7 @@
 :- interface.
 :- import_module io.

-:- pred main(io__state :: di, io__state :: uo) is det.
+:- pred main(io.state :: di, io.state :: uo) is det.

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

@@ -25,126 +27,123 @@

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

-	% main: top-level predicate.
-main -->
-	io__command_line_arguments(Args0),
-	{ options__get_option_ops(OptionOps) },
-	{ getopt__process_options(OptionOps, Args0, Args, Result0) },
-	postprocess_options(Result0, Result),
-	( { Result = yes(Msg) },
-		usage_error(Msg)
-	; { Result = no },
-		globals__io_get_output_style(OutputStyle),
-		( { OutputStyle = help_only } ->
-			usage
-		; { OutputStyle = version_only } ->
-			version
-		;
-			main_2(Args)
-		)
-	).
-
-%-----------------------------------------------------------------------------%
-
-:- pred usage_error(string :: in, io__state :: di, io__state :: uo) is det.
-usage_error(Msg) -->
-	io__progname_base("diff", ProgName),
-	io__stderr_stream(StdErr),
-	io__write_strings(StdErr, [ProgName, ": ", Msg, "\n"]),
-	io__set_exit_status(1),
-	usage.
-
-:- pred usage_io_error(io__error, io__state, io__state).
-:- mode usage_io_error(in, di, uo) is det.
-usage_io_error(Error) -->
-	{ io__error_message(Error, Msg) },
-	usage_error(Msg).
-
-:- pred usage(io__state :: di, io__state :: uo) is det.
-usage -->
-	io__write_string("Usage: diff [options] from-file to-file\n\n"),
-	options_help.
-
-:- pred version(io__state :: di, io__state :: uo) is det.
-version -->
-	io__write_string("diff - Mercury diff version 0.4\n").
-
-%-----------------------------------------------------------------------------%
-
-	% main_2 analyses the command-line arguments which are not
-	% options and calls diff__do_diff.
-:- pred main_2(list(string), io__state, io__state).
-:- mode main_2(in, di, uo) is det.
-main_2([]) -->
-	usage_error("missing operand").
-main_2([Fname1 | Rest]) -->
-	( { Rest = [Fname2 | _] },
-		( { Fname1 = Fname2 } ->
-			% Not sure why anyone would want to diff two
-			% files with the same name, but just in case...
-			( { Fname1 = "-" } ->
-				file__read_input(Fname1, Contents1),
-				{ Contents1 = Contents2 }
-			;
-				file__read_file(Fname1, Contents1),
-				{ Contents1 = Contents2 }
-			)
-		;
-			% If either file is "-", simply use standard input.
-			% (Note: Both can't be "-" since that was dealt with
-			% in the previous case.)
-			( { Fname1 = "-" } ->
-				file__read_input(Fname1, Contents1),
-				file__read_file(Fname2, Contents2)
-			; { Fname2 = "-" } ->
-				file__read_file(Fname1, Contents1),
-				file__read_input(Fname2, Contents2)
-			;
-			% Otherwise read the files normally.
-				file__read_file(Fname1, Contents1),
-				file__read_file(Fname2, Contents2)
-			)
-		),
-		% Now do the diff.
-		( { Contents1 = ok(File1), Contents2 = ok(File2) } ->
-			diff__do_diff(File1, File2)
-		; { Contents1 = error(Msg) } ->
-			usage_io_error(Msg)
-		; { Contents2 = error(Msg) } ->
-			usage_io_error(Msg)
-		;
-			{ error("main2") }
-		)
-	; { Rest = [] },
-		usage_error("missing operand")
-	).
-
-%-----------------------------------------------------------------------------%
-
-	% diff__do_diff takes the files plus all the command
-	% line options and determines what to do with them.
-	%
-	% At the moment, we're organised into four passes:
-	%
-	%	- build_matches determines which lines from the
-	%	  input files match (using the appropriate command-
-	%	  line options).
-	%	- diff_by_myers takes the matches produced and
-	%	  computes a diff between them.
-	%	- filter_diff analyses the diff, filtering out
-	%	  any edits which the user said that they didn't
-	%	  want to see (using the appropriate command-line
-	%	  options).
-	%	- display_diff outputs the diff in whatever output
-	%	  format the user chose.
-	%
-:- pred diff__do_diff(file, file, io__state, io__state).
-:- mode diff__do_diff(in, in, di, uo) is det.
-diff__do_diff(File1, File2) -->
-	build_matches(File1, File2, FileX, FileY),
-	diff_by_myers(FileX, FileY, Diff0),
-	filter_diff(Diff0, File1, File2, Diff),
-	display_diff(File1, File2, Diff).
+    % main: top-level predicate.
+main(!IO) :-
+    io.command_line_arguments(Args0, !IO),
+    options.get_option_ops(OptionOps),
+    getopt.process_options(OptionOps, Args0, Args, Result0),
+    postprocess_options(Result0, Result, !IO),
+    ( Result = yes(Msg),
+        usage_error(Msg, !IO)
+    ; Result = no,
+        globals.io_get_output_style(OutputStyle, !IO),
+        ( OutputStyle = help_only ->
+            usage(!IO)
+        ; OutputStyle = version_only ->
+            version(!IO)
+        ;
+            main_2(Args, !IO)
+        )
+    ).
+
+%-----------------------------------------------------------------------------%
+
+:- pred usage_error(string :: in, io.state :: di, io.state :: uo) is det.
+usage_error(Msg, !IO) :-
+    io.progname_base("diff", ProgName, !IO),
+    io.stderr_stream(StdErr, !IO),
+    io.write_strings(StdErr, [ProgName, ": ", Msg, "\n"], !IO),
+    io.set_exit_status(1, !IO),
+    usage(!IO).
+
+:- pred usage_io_error(io.error::in, io.state::di, io.state::uo) is det.
+usage_io_error(Error, !IO) :-
+    io.error_message(Error, Msg),
+    usage_error(Msg, !IO).
+
+:- pred usage(io.state :: di, io.state :: uo) is det.
+usage(!IO) :-
+    io.write_string("Usage: diff [options] from-file to-file\n\n", !IO),
+    options_help(!IO).
+
+:- pred version(io.state :: di, io.state :: uo) is det.
+version(!IO) :-
+    io.write_string("diff - Mercury diff version 0.4\n", !IO).
+
+%-----------------------------------------------------------------------------%
+
+    % main_2 analyses the command-line arguments which are not
+    % options and calls diff.do_diff.
+:- pred main_2(list(string)::in, io.state::di, io.state::uo) is det.
+main_2([], !IO) :-
+    usage_error("missing operand", !IO).
+main_2([Fname1 | Rest], !IO) :-
+    ( Rest = [Fname2 | _],
+        ( Fname1 = Fname2 ->
+            % Not sure why anyone would want to diff two
+            % files with the same name, but just in case...
+            ( Fname1 = "-" ->
+                file.read_input(Fname1, Contents1, !IO),
+                Contents1 = Contents2
+            ;
+                file.read_file(Fname1, Contents1, !IO),
+                Contents1 = Contents2
+            )
+        ;
+            % If either file is "-", simply use standard input.
+            % (Note: Both can't be "-" since that was dealt with
+            % in the previous case.)
+            ( Fname1 = "-" ->
+                file.read_input(Fname1, Contents1, !IO),
+                file.read_file(Fname2, Contents2, !IO)
+            ; Fname2 = "-" ->
+                file.read_file(Fname1, Contents1, !IO),
+                file.read_input(Fname2, Contents2, !IO)
+            ;
+            % Otherwise read the files normally.
+                file.read_file(Fname1, Contents1, !IO),
+                file.read_file(Fname2, Contents2, !IO)
+            )
+        ),
+        % Now do the diff.
+        ( Contents1 = ok(File1), Contents2 = ok(File2) ->
+            diff.do_diff(File1, File2, !IO)
+        ; Contents1 = error(Msg) ->
+            usage_io_error(Msg, !IO)
+        ; Contents2 = error(Msg) ->
+            usage_io_error(Msg, !IO)
+        ;
+            error("main2")
+        )
+    ; Rest = [],
+        usage_error("missing operand", !IO)
+    ).
+
+%-----------------------------------------------------------------------------%
+
+    % diff.do_diff takes the files plus all the command
+    % line options and determines what to do with them.
+    %
+    % At the moment, we're organised into four passes:
+    %
+    %   - build_matches determines which lines from the
+    %     input files match (using the appropriate command-
+    %     line options).
+    %   - diff_by_myers takes the matches produced and
+    %     computes a diff between them.
+    %   - filter_diff analyses the diff, filtering out
+    %     any edits which the user said that they didn't
+    %     want to see (using the appropriate command-line
+    %     options).
+    %   - display_diff outputs the diff in whatever output
+    %     format the user chose.
+    %
+:- pred diff.do_diff(file::in, file::in, io.state::di, io.state::uo) is det.
+diff.do_diff(File1, File2, !IO) :-
+    build_matches(File1, File2, FileX, FileY, !IO),
+    diff_by_myers(FileX, FileY, Diff0, !IO),
+    filter_diff(Diff0, File1, File2, Diff, !IO),
+    display_diff(File1, File2, Diff, !IO).

 %-----------------------------------------------------------------------------%
 %-----------------------------------------------------------------------------%
Index: samples/diff/diff_out.m
===================================================================
RCS file: /home/mercury1/repository/mercury/samples/diff/diff_out.m,v
retrieving revision 1.2
diff -u -r1.2 diff_out.m
--- samples/diff/diff_out.m	15 Sep 1998 04:54:22 -0000	1.2
+++ samples/diff/diff_out.m	24 Apr 2006 05:48:16 -0000
@@ -1,4 +1,6 @@
 %-----------------------------------------------------------------------------%
+% vim: ft=mercury ts=4 sw=4 et
+%-----------------------------------------------------------------------------%
 % Copyright (C) 1995-1998 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.
@@ -20,44 +22,39 @@

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

-:- type diff_out__output_style
-	--->	normal
-	;	help_only
-	;	version_only
-	;	context(int)
-	;	unified(int)
-	;	ed
-	;	forward_ed
-	;	rcs
-	;	ifdef(string)
-	;	brief
-	;	side_by_side
-	;	cvs_merge_conflict.
-
-	% The default output style.
-:- pred diff_out__default_output_style(diff_out__output_style).
-:- mode diff_out__default_output_style(out) is det.
-
-	% Succeeds if, for this output style, an absence of differences
-	% means that no output should be generated.
-:- pred diff_out__no_diff_implies_no_output(diff_out__output_style).
-:- mode diff_out__no_diff_implies_no_output(in) is semidet.
-
-	% Succeeds if the user only wants to know about the presence
-	% of any differences, not what they actually are.
-:- pred diff_out__full_diff_not_required(diff_out__output_style).
-:- mode diff_out__full_diff_not_required(in) is semidet.
-
-	% Succeeds if the output style is "robust", that is, the
-	% absence of a newline at the end of the file actually
-	% matters.
-:- pred diff_out__robust(diff_out__output_style).
-:- mode diff_out__robust(in) is semidet.
-
-	% display_diff takes a diff and displays it
-	% in the user's specified output format.
-:- pred display_diff(file, file, diff, io__state, io__state).
-:- mode display_diff(in, in, in, di, uo) is det.
+:- type diff_out.output_style
+    --->    normal
+    ;   help_only
+    ;   version_only
+    ;   context(int)
+    ;   unified(int)
+    ;   ed
+    ;   forward_ed
+    ;   rcs
+    ;   ifdef(string)
+    ;   brief
+    ;   side_by_side
+    ;   cvs_merge_conflict.
+
+    % The default output style.
+:- pred diff_out.default_output_style(diff_out.output_style::out) is det.
+
+    % Succeeds if, for this output style, an absence of differences
+    % means that no output should be generated.
+:- pred diff_out.no_diff_implies_no_output(output_style::in) is semidet.
+
+    % Succeeds if the user only wants to know about the presence
+    % of any differences, not what they actually are.
+:- pred diff_out.full_diff_not_required(diff_out.output_style::in) is semidet.
+
+    % Succeeds if the output style is "robust", that is, the
+    % absence of a newline at the end of the file actually
+    % matters.
+:- pred diff_out.robust(diff_out.output_style::in) is semidet.
+
+    % display_diff takes a diff and displays it
+    % in the user's specified output format.
+:- pred display_diff(file::in, file::in, diff::in, io::di, io::uo) is det.

 %-----------------------------------------------------------------------------%
 %-----------------------------------------------------------------------------%
@@ -66,968 +63,956 @@
 :- import_module globals, options.
 :- import_module require, std_util, int, list, char, string, bool.

-diff_out__default_output_style(normal).
+diff_out.default_output_style(normal).

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

-diff_out__no_diff_implies_no_output(normal).
-diff_out__no_diff_implies_no_output(context(_)).
-diff_out__no_diff_implies_no_output(unified(_)).
-diff_out__no_diff_implies_no_output(ed).
-diff_out__no_diff_implies_no_output(forward_ed).
-diff_out__no_diff_implies_no_output(rcs).
-diff_out__no_diff_implies_no_output(brief).
-
-%-----------------------------------------------------------------------------%
-
-diff_out__full_diff_not_required(brief).
-
-%-----------------------------------------------------------------------------%
-
-diff_out__robust(normal).
-diff_out__robust(context(_)).
-diff_out__robust(unified(_)).
-diff_out__robust(rcs).
-diff_out__robust(ifdef(_)).
-diff_out__robust(side_by_side).
-diff_out__robust(cvs_merge_conflict).
-
-%-----------------------------------------------------------------------------%
-
-	% diff_out__show_file shows the segment of the file
-	% from Low to High, with each line preceeded by
-	% the Prefix characher and a space.  The diff(1)
-	% format specifies that the lines effected in the
-	% first file should be flagged by '<' and the
-	% lines effected in the second file should be
-	% flagged by '>'.
-	%
-:- pred diff_out__show_file(file, string, pos, pos, io__state, io__state).
-:- mode diff_out__show_file(in, in, in, in, di, uo) is det.
-
-diff_out__show_file(File, Prefix, Low, High) -->
-	globals__io_lookup_bool_option(expand_tabs, ExpandTabs),
-	diff_out__show_file_2(ExpandTabs, File, Prefix, Low, High).
-
-	% NOTE: GCC 2.7.2 under Digital Unix 3.2 doesn't compile
-	%       this predicate correctly with optimisation turned on.
-:- pred diff_out__show_file_2(bool, file, string, pos, pos,
-		io__state, io__state).
-:- mode diff_out__show_file_2(in, in, in, in, in, di, uo) is det.
-
-diff_out__show_file_2(ExpandTabs, File, Prefix, Low, High) -->
-	( { Low < High } ->
-		( { file__get_line(File, Low, Line) } ->
-			io__write_string(Prefix),
-			( { ExpandTabs = yes },
-				{ string__to_char_list(Line, LineList) },
-				diff_out__expand_tabs(LineList, 0)
-			; { ExpandTabs = no },
-				io__write_string(Line)
-			),
-			diff_out__show_file_2(ExpandTabs, File, Prefix,
-					Low + 1, High)
-		;
-			{ error("diff_out_show_file: file ended prematurely") }
-		)
-	;
-		[]
-	).
-
-:- pred diff_out__expand_tabs(list(char), int, io__state, io__state).
-:- mode diff_out__expand_tabs(in, in, di, uo) is det.
-
-diff_out__expand_tabs([], _) --> [].
-diff_out__expand_tabs([C | Cs], Pos) -->
-	( { C = '\t' } ->
-		{ Spaces = tab_width - (Pos rem tab_width) },
-		put_spaces(Spaces, Pos, NewPos),
-		diff_out__expand_tabs(Cs, NewPos)
-	;
-		io__write_char(C),
-		diff_out__expand_tabs(Cs, Pos + 1)
-	).
-
-%-----------------------------------------------------------------------------%
-%-----------------------------------------------------------------------------%
-
-
-	% display_diff: Determine which output style to use, then call
-	% the predicate to display that output.
-	%
-	% Some of these options (notably the ones which require no
-	% output) should have been handled already by the time we
-	% reach here.  In those cases, we just call error/1.
-display_diff(File1, File2, Diff) -->
-	globals__io_get_output_style(OutputStyle),
-	(
-		{ Diff = [],
-		  diff_out__no_diff_implies_no_output(OutputStyle)
-		}
-	->
-		[]
-	;
-		display_diff_2(OutputStyle, File1, File2, Diff)
-	).
-
-
-:- pred display_diff_2(diff_out__output_style, file, file, diff,
-			io__state, io__state).
-:- mode display_diff_2(in, in, in, in, di, uo) is det.
-
-display_diff_2(normal, File1, File2, Diff) -->
-	display_diff_normal(File1, File2, Diff).
-
-display_diff_2(help_only, _File1, _File2, _Diff) -->
-	{ error("display_diff: help_only") }.
-
-display_diff_2(version_only, _File1, _File2, _Diff) -->
-	{ error("display_diff: version_only") }.
-
-display_diff_2(context(Context), File1, File2, Diff) -->
-	display_context_diff(Context, File1, File2, Diff).
-
-display_diff_2(unified(Context), File1, File2, Diff) -->
-	display_unified_diff(Context, File1, File2, Diff).
-
-display_diff_2(ed, File1, File2, Diff) -->
-	display_diff_ed(File1, File2, Diff).
-
-display_diff_2(forward_ed, File1, File2, Diff) -->
-	display_diff_forward_ed(File1, File2, Diff).
-
-display_diff_2(rcs, File1, File2, Diff) -->
-	display_diff_rcs(File1, File2, Diff).
-
-display_diff_2(ifdef(Sym), File1, File2, Diff) -->
-	display_diff_ifdef(Sym, File1, File2, Diff).
-
-display_diff_2(brief, File1, File2, _Diff) -->
-	% XXX For this output style, we really don't need to
-	%     perform a complete diff.  This should be handled
-	%     higher up for efficiency.
-	{ file__get_file_name(File1, FileName1) },
-	{ file__get_file_name(File2, FileName2) },
-	io__write_strings(["Files ", FileName1, " and ",
-		FileName2, " differ\n"]).
-
-display_diff_2(side_by_side, File1, File2, Diff) -->
-	display_diff_side_by_side(File1, File2, Diff).
-
-display_diff_2(cvs_merge_conflict, File1, File2, Diff) -->
-	display_diff_cvs_merge_conflict(File1, File2, Diff).
-
-%-----------------------------------------------------------------------------%
-
-	% display_diff_normal takes a diff and displays it
-	% in the standard diff(1) output format.
-:- pred display_diff_normal(file, file, diff, io__state, io__state).
-:- mode display_diff_normal(in, in, in, di, uo) is det.
-
-display_diff_normal(File1, File2, Diff) -->
-	globals__io_lookup_bool_option(initial_tab, InitialTab),
-	{ InitialTab = no,
-		FromStr = "< ",
-		ToStr = "> "
-	; InitialTab = yes,
-		FromStr = "<\t",
-		ToStr = ">\t"
-	},
-	display_diff_normal_2(File1, File2, Diff, FromStr, ToStr).
-
-	% display_diff_normal takes a diff and displays it
-	% in the standard diff(1) output format.
-:- pred display_diff_normal_2(file, file, diff, string, string,
-			io__state, io__state).
-:- mode display_diff_normal_2(in, in, in, in, in, di, uo) is det.
-
-display_diff_normal_2(_, _, [], _, _) --> [].
-display_diff_normal_2(File1, File2, [SingDiff | Diff], FromStr, ToStr) -->
-	( { SingDiff = add(X, Y1 - Y2) },
-		diff_out__write_command(X - X, 'a', Y1 - Y2),
-		diff_out__show_file(File2, ToStr, Y1, Y2)
-	; { SingDiff = delete(X1 - X2, Y) },
-		diff_out__write_command(X1 - X2, 'd', Y - Y),
-		diff_out__show_file(File1, FromStr, X1, X2)
-	; { SingDiff = change(X1 - X2, Y1 - Y2) },
-		diff_out__write_command(X1 - X2, 'c', Y1 - Y2),
-		diff_out__show_file(File1, FromStr, X1, X2),
-		io__write_string("---\n"),
-		diff_out__show_file(File2, ToStr, Y1, Y2)
-	),
-	display_diff_normal_2(File1, File2, Diff, FromStr, ToStr).
-
-
-	% diff_out__write_command displays a diff(1) command.
-	% Like ed(1), a pair of numbers which are identical
-	% are abbreviated by a single number.
-	% MK: Assumption X=<X2
-	% AJB: And, similarly, Y=<Y2.  This is actually an
-	%      invariant of the segment type.  See difftype.m.
-:- pred diff_out__write_command(segment, char, segment, io__state, io__state).
-:- mode diff_out__write_command(in, in, in, di, uo) is det.
-
-diff_out__write_command(X - X2, C, Y - Y2) -->
-	{ X1 is X + 1 },	% Convert from pos to line number
-	( { X1 >= X2 } ->
-		% either empty or singleton segment
-		io__write_int(X2)
-	;
-		io__write_int(X1),
-		io__write_char(','),
-		io__write_int(X2)
-	),
-	io__write_char(C),
-	{ Y1 is Y + 1 },	% Convert from pos to line number
-	( { Y1 >= Y2 } ->
-		% either empty or singleton segment
-		io__write_int(Y2)
-	;
-		io__write_int(Y1),
-		io__write_char(','),
-		io__write_int(Y2)
-	),
-	io__write_char('\n').
-
-%-----------------------------------------------------------------------------%
-
-	% display_diff_rcs takes a diff and displays it
-	% in the RCS difference format.
-:- pred display_diff_rcs(file, file, diff, io__state, io__state).
-:- mode display_diff_rcs(in, in, in, di, uo) is det.
-
-display_diff_rcs(_File1, _File2, []) --> [].
-display_diff_rcs(File1, File2, [Cmd | Diff]) -->
-	( { Cmd = add(X, Y1 - Y2) },
-		diff_out__write_command_rcs('a', X, Y2-Y1),
-		diff_out__show_file(File2, "", Y1, Y2)
-	; { Cmd = delete(X1 - X2, _Y) },
-		diff_out__write_command_rcs('d', X1, X2-X1)
-	; { Cmd = change(X1 - X2, Y1 - Y2) },
-		diff_out__write_command_rcs('d', X1, X2-X1),
-		diff_out__write_command_rcs('a', X1, Y2-Y1),
-		diff_out__show_file(File2, "", Y1, Y2)
-	),
-	display_diff_rcs(File1, File2, Diff).
-
-
-	% diff_out__write_command_rcs displays a diff command in
-	% the RCS ,v format.
-:- pred diff_out__write_command_rcs(char, int, int, io__state, io__state).
-:- mode diff_out__write_command_rcs(in, in, in, di, uo) is det.
-
-diff_out__write_command_rcs(C, X, Y) -->
-	io__write_char(C),
-	io__write_int(X + 1),	% Convert from pos to line number
-	io__write_char(' '),
-	io__write_int(Y),
-	io__write_char('\n').
-
-%-----------------------------------------------------------------------------%
-
-	% display_diff_ed takes a diff and displays it
-	% in ed(1) format, but with all diffs backward.
-:- pred display_diff_ed(file, file, diff, io__state, io__state).
-:- mode display_diff_ed(in, in, in, di, uo) is det.
-
-display_diff_ed(_File1, _File2, []) --> [].
-display_diff_ed(File1, File2, [Cmd | Diff]) -->
-	display_diff_ed(File1, File2, Diff),
-	( { Cmd = add(X, Y1 - Y2) },
-		diff_out__write_command_ed(X - X, 'a'),
-		diff_out__show_file(File2, "", Y1, Y2),
-		io__write_string(".\n")
-	; { Cmd = delete(X, _Y) },
-		diff_out__write_command_ed(X, 'd')
-	; { Cmd = change(X, Y1 - Y2) },
-		diff_out__write_command_ed(X, 'c'),
-		diff_out__show_file(File2, "", Y1, Y2),
-		io__write_string(".\n")
-	).
-
-
-	% diff_out__write_command_ed displays an ed(1) command.
-:- pred diff_out__write_command_ed(segment, char, io__state, io__state).
-:- mode diff_out__write_command_ed(in, in, di, uo) is det.
-
-diff_out__write_command_ed(X - X2, C) -->
-	{ X1 is X + 1 },		% Convert from pos to line number
-	( { X1 >= X2 } ->
-		% either empty or singleton segment
-		io__write_int(X2)
-	;
-		io__write_int(X1),
-		io__write_char(','),
-		io__write_int(X2)
-	),
-	io__write_char(C),
-	io__write_char('\n').
-
-%-----------------------------------------------------------------------------%
-
-	% display_diff_forward_ed takes a diff and displays it
-	% in ed(1) format, but with all diff_out forward.  This
-	% is actually useless for feeding to ed(1), but nicer
-	% to read.
-:- pred display_diff_forward_ed(file, file, diff, io__state, io__state).
-:- mode display_diff_forward_ed(in, in, in, di, uo) is det.
-
-display_diff_forward_ed(_File1, _File2, []) --> { true }.
-display_diff_forward_ed(File1, File2, [Cmd | Diff]) -->
-	( { Cmd = add(X, Y1 - Y2) },
-		diff_out__write_command_forward_ed(X - X, 'a'),
-		diff_out__show_file(File2, "", Y1, Y2),
-		io__write_string(".\n")
-	; { Cmd = delete(X, _Y) },
-		diff_out__write_command_forward_ed(X, 'd')
-	; { Cmd = change(X, Y1 - Y2) },
-		diff_out__write_command_forward_ed(X, 'c'),
-		diff_out__show_file(File2, "", Y1, Y2),
-		io__write_string(".\n")
-	),
-	display_diff_forward_ed(File1, File2, Diff).
-
-	% diff_out__write_command_forward_ed displays a forward ed(1)
-	% command.  The difference between this and write_command_ed is
-	% that the command char comes first here.  Who comes up with
-	% these dumb formats anyway?
-:- pred diff_out__write_command_forward_ed(segment, char, io__state,
io__state).
-:- mode diff_out__write_command_forward_ed(in, in, di, uo) is det.
-diff_out__write_command_forward_ed(X - X2, C) -->
-	io__write_char(C),
-	{ X1 is X + 1 },		% Convert from pos to line number
-	( { X1 >= X2 } ->
-		% either empty or singleton segment
-		io__write_int(X2)
-	;
-		io__write_int(X1),
-		io__write_char(' '),
-		io__write_int(X2)
-	),
-	io__write_char('\n').
-
-%-----------------------------------------------------------------------------%
-%-----------------------------------------------------------------------------%
-
-	% display_diff_ifdef writes out the files in a unified diff,
-	% using #ifdefs around each edit.
-	%
-	% TO DO: GNU diff makes this output style much more
-	%        configurable.  We should too.
-:- pred display_diff_ifdef(string, file, file, diff, io__state, io__state).
-:- mode display_diff_ifdef(in, in, in, in, di, uo) is det.
-
-display_diff_ifdef(Sym, File1, File2, Diff) -->
-	display_diff_ifdef_2(0, Sym, File1, File2, Diff).
-
-	% Argument 1 (prev) is the last pos displayed before
-	% the current edit (or end of edits, in the base case).
-	% This is important for when we have to display the
-	% "non-diffed" text between edits.
-:- pred display_diff_ifdef_2(int, string, file, file, diff,
-		io__state, io__state).
-:- mode display_diff_ifdef_2(in, in, in, in, in, di, uo) is det.
-
-display_diff_ifdef_2(Prev, _Sym, File1, _File2, []) -->
-	{ file__get_numlines(File1, SegEnd) },
-	diff_out__show_file(File1, "", Prev, SegEnd).
-display_diff_ifdef_2(Prev, Sym, File1, File2, [Edit | Diff]) -->
-	{ first_mentioned_positions(Edit, StartOfEdit, _) },
-	diff_out__show_file(File1, "", Prev, StartOfEdit),
-	( { Edit = add(X, Y1 - Y2) },
-		io__write_strings(["#ifdef ", Sym, "\n"]),
-		diff_out__show_file(File2, "", Y1, Y2),
-		io__write_strings(["#endif /* ", Sym, " */\n"]),
-		{ Next = X }
-	; { Edit = delete(X1 - X2, _) },
-		io__write_strings(["#ifndef ", Sym, "\n"]),
-		diff_out__show_file(File1, "", X1, X2),
-		io__write_strings(["#endif /* not ", Sym, " */\n"]),
-		{ Next = X2 }
-	; { Edit = change(X1 - X2, Y1 - Y2) },
-		io__write_strings(["#ifndef ", Sym, "\n"]),
-		diff_out__show_file(File1, "", X1, X2),
-		io__write_strings(["#else /* ", Sym, " */\n"]),
-		diff_out__show_file(File2, "", Y1, Y2),
-		io__write_strings(["#endif /* ", Sym, " */\n"]),
-		{ Next = X2 }
-	),
-	display_diff_ifdef_2(Next, Sym, File1, File2, Diff).
-
-%-----------------------------------------------------------------------------%
-%-----------------------------------------------------------------------------%
-
-	% display_diff_cvs_merge_conflict writes out the files in a
-	% unified diff, using CVS merge conflict marks around each edit.
-	%
-:- pred display_diff_cvs_merge_conflict(file, file, diff, io__state,
io__state).
-:- mode display_diff_cvs_merge_conflict(in, in, in, di, uo) is det.
-
-display_diff_cvs_merge_conflict(File1, File2, Diff) -->
-	display_diff_cvs_merge_conflict_2(0, File1, File2, Diff).
-
-	% Argument 1 (prev) is the last pos displayed before
-	% the current edit (or end of edits, in the base case).
-	% This is important for when we have to display the
-	% "non-diffed" text between edits.
-:- pred display_diff_cvs_merge_conflict_2(int, file, file, diff,
-		io__state, io__state).
-:- mode display_diff_cvs_merge_conflict_2(in, in, in, in, di, uo) is det.
-
-display_diff_cvs_merge_conflict_2(Prev, File1, _File2, []) -->
-	{ file__get_numlines(File1, SegEnd) },
-	diff_out__show_file(File1, "", Prev, SegEnd).
-display_diff_cvs_merge_conflict_2(Prev, File1, File2, [Edit | Diff]) -->
-	{ first_mentioned_positions(Edit, StartOfEdit, _) },
-	diff_out__show_file(File1, "", Prev, StartOfEdit),
-	{ file__get_file_name(File1, FileName1) },
-	{ file__get_file_name(File2, FileName2) },
-	( { Edit = add(X, Y1 - Y2) },
-		io__write_strings(["<<<<<<< ", FileName1, "\n"]),
-		diff_out__show_file(File2, "", Y1, Y2),
-		io__write_string("=======\n"),
-		io__write_strings([">>>>>>> ", FileName2, "\n"]),
-		{ Next = X }
-	; { Edit = delete(X1 - X2, _) },
-		io__write_strings(["<<<<<<< ", FileName1, "\n"]),
-		io__write_string("=======\n"),
-		diff_out__show_file(File1, "", X1, X2),
-		io__write_strings([">>>>>>> ", FileName2, "\n"]),
-		{ Next = X2 }
-	; { Edit = change(X1 - X2, Y1 - Y2) },
-		io__write_strings(["<<<<<<< ", FileName1, "\n"]),
-		diff_out__show_file(File1, "", X1, X2),
-		io__write_string("=======\n"),
-		diff_out__show_file(File2, "", Y1, Y2),
-		io__write_strings([">>>>>>> ", FileName2, "\n"]),
-		{ Next = X2 }
-	),
-	display_diff_cvs_merge_conflict_2(Next, File1, File2, Diff).
-
-%-----------------------------------------------------------------------------%
-%-----------------------------------------------------------------------------%
-
-	% Types for context/unified diffs.
-
-	% A context diff is a bit more complicated than a "standard"
-	% diff, because it requires the display of some parts of the
-	% files which are not actually part of the diff, but not all
-	% of it.
-	%
-	% Because context and unified diffs both require the same
-	% kind of information, we factor out the code to turn a
-	% normal diff into a context diff.
+diff_out.no_diff_implies_no_output(normal).
+diff_out.no_diff_implies_no_output(context(_)).
+diff_out.no_diff_implies_no_output(unified(_)).
+diff_out.no_diff_implies_no_output(ed).
+diff_out.no_diff_implies_no_output(forward_ed).
+diff_out.no_diff_implies_no_output(rcs).
+diff_out.no_diff_implies_no_output(brief).
+
+%-----------------------------------------------------------------------------%
+
+diff_out.full_diff_not_required(brief).
+
+%-----------------------------------------------------------------------------%
+
+diff_out.robust(normal).
+diff_out.robust(context(_)).
+diff_out.robust(unified(_)).
+diff_out.robust(rcs).
+diff_out.robust(ifdef(_)).
+diff_out.robust(side_by_side).
+diff_out.robust(cvs_merge_conflict).
+
+%-----------------------------------------------------------------------------%
+
+    % diff_out.show_file shows the segment of the file
+    % from Low to High, with each line preceeded by
+    % the Prefix characher and a space.  The diff(1)
+    % format specifies that the lines effected in the
+    % first file should be flagged by '<' and the
+    % lines effected in the second file should be
+    % flagged by '>'.
+    %
+:- pred diff_out.show_file(file::in, string::in, pos::in, pos::in,
+        io.state::di, io.state::uo) is det.
+
+diff_out.show_file(File, Prefix, Low, High, !IO) :-
+    globals.io_lookup_bool_option(expand_tabs, ExpandTabs, !IO),
+    diff_out.show_file_2(ExpandTabs, File, Prefix, Low, High, !IO).
+
+    % NOTE: GCC 2.7.2 under Digital Unix 3.2 doesn't compile
+    %       this predicate correctly with optimisation turned on.
+:- pred diff_out.show_file_2(bool::in, file::in, string::in, pos::in, pos::in,
+        io.state::di, io.state::uo) is det.
+
+diff_out.show_file_2(ExpandTabs, File, Prefix, Low, High, !IO) :-
+    ( Low < High ->
+        ( file.get_line(File, Low, Line) ->
+            io.write_string(Prefix, !IO),
+            ( ExpandTabs = yes,
+                string.to_char_list(Line, LineList),
+                diff_out.expand_tabs(LineList, 0, !IO)
+            ; ExpandTabs = no,
+                io.write_string(Line, !IO)
+            ),
+            diff_out.show_file_2(ExpandTabs, File, Prefix,
+                    Low + 1, High, !IO)
+        ;
+            error("diff_out_show_file: file ended prematurely")
+        )
+    ;
+        true
+    ).
+
+:- pred diff_out.expand_tabs(list(char)::in, int::in, io.state::di,
+        io.state::uo) is det.
+
+diff_out.expand_tabs([], _, !IO).
+diff_out.expand_tabs([C | Cs], Pos, !IO) :-
+    ( C = '\t' ->
+        Spaces = tab_width - (Pos rem tab_width),
+        put_spaces(Spaces, Pos, NewPos, !IO),
+        diff_out.expand_tabs(Cs, NewPos, !IO)
+    ;
+        io.write_char(C, !IO),
+        diff_out.expand_tabs(Cs, Pos + 1, !IO)
+    ).
+
+%-----------------------------------------------------------------------------%
+%-----------------------------------------------------------------------------%
+
+
+    % display_diff: Determine which output style to use, then call
+    % the predicate to display that output.
+    %
+    % Some of these options (notably the ones which require no
+    % output) should have been handled already by the time we
+    % reach here.  In those cases, we just call error/1.
+display_diff(File1, File2, Diff, !IO) :-
+    globals.io_get_output_style(OutputStyle, !IO),
+    (
+        Diff = [],
+        diff_out.no_diff_implies_no_output(OutputStyle)
+    ->
+        true
+    ;
+        display_diff_2(OutputStyle, File1, File2, Diff, !IO)
+    ).
+
+
+:- pred display_diff_2(diff_out.output_style::in, file::in, file::in, diff::in,
+            io.state::di, io.state::uo) is det.
+
+display_diff_2(normal, File1, File2, Diff, !IO) :-
+    display_diff_normal(File1, File2, Diff, !IO).
+
+display_diff_2(help_only, _File1, _File2, _Diff, !IO) :-
+    error("display_diff: help_only").
+
+display_diff_2(version_only, _File1, _File2, _Diff, !IO) :-
+    error("display_diff: version_only").
+
+display_diff_2(context(Context), File1, File2, Diff, !IO) :-
+    display_context_diff(Context, File1, File2, Diff, !IO).
+
+display_diff_2(unified(Context), File1, File2, Diff, !IO) :-
+    display_unified_diff(Context, File1, File2, Diff, !IO).
+
+display_diff_2(ed, File1, File2, Diff, !IO) :-
+    display_diff_ed(File1, File2, Diff, !IO).
+
+display_diff_2(forward_ed, File1, File2, Diff, !IO) :-
+    display_diff_forward_ed(File1, File2, Diff, !IO).
+
+display_diff_2(rcs, File1, File2, Diff, !IO) :-
+    display_diff_rcs(File1, File2, Diff, !IO).
+
+display_diff_2(ifdef(Sym), File1, File2, Diff, !IO) :-
+    display_diff_ifdef(Sym, File1, File2, Diff, !IO).
+
+display_diff_2(brief, File1, File2, _Diff, !IO) :-
+    % XXX For this output style, we really don't need to
+    %     perform a complete diff.  This should be handled
+    %     higher up for efficiency.
+    file.get_file_name(File1, FileName1),
+    file.get_file_name(File2, FileName2),
+    io.write_strings(["Files ", FileName1, " and ",
+        FileName2, " differ\n"], !IO).
+
+display_diff_2(side_by_side, File1, File2, Diff, !IO) :-
+    display_diff_side_by_side(File1, File2, Diff, !IO).
+
+display_diff_2(cvs_merge_conflict, File1, File2, Diff, !IO) :-
+    display_diff_cvs_merge_conflict(File1, File2, Diff, !IO).
+
+%-----------------------------------------------------------------------------%
+
+    % display_diff_normal takes a diff and displays it
+    % in the standard diff(1) output format.
+:- pred display_diff_normal(file::in, file::in, diff::in,
+        io.state::di, io.state::uo) is det.
+
+display_diff_normal(File1, File2, Diff, !IO) :-
+    globals.io_lookup_bool_option(initial_tab, InitialTab, !IO),
+    ( InitialTab = no,
+        FromStr = "< ",
+        ToStr = "> "
+    ; InitialTab = yes,
+        FromStr = "<\t",
+        ToStr = ">\t"
+    ),
+    display_diff_normal_2(File1, File2, Diff, FromStr, ToStr, !IO).
+
+    % display_diff_normal takes a diff and displays it
+    % in the standard diff(1) output format.
+:- pred display_diff_normal_2(file::in, file::in, diff::in, string::in,
+        string::in, io.state::di, io.state::uo) is det.
+
+display_diff_normal_2(_, _, [], _, _, !IO).
+display_diff_normal_2(File1, File2, [SingDiff | Diff], FromStr, ToStr, !IO) :-
+    ( SingDiff = add(X, Y1 - Y2),
+        diff_out.write_command(X - X, 'a', Y1 - Y2, !IO),
+        diff_out.show_file(File2, ToStr, Y1, Y2, !IO)
+    ; SingDiff = delete(X1 - X2, Y),
+        diff_out.write_command(X1 - X2, 'd', Y - Y, !IO),
+        diff_out.show_file(File1, FromStr, X1, X2, !IO)
+    ; SingDiff = change(X1 - X2, Y1 - Y2),
+        diff_out.write_command(X1 - X2, 'c', Y1 - Y2, !IO),
+        diff_out.show_file(File1, FromStr, X1, X2, !IO),
+        io.write_string("---\n", !IO),
+        diff_out.show_file(File2, ToStr, Y1, Y2, !IO)
+    ),
+    display_diff_normal_2(File1, File2, Diff, FromStr, ToStr, !IO).
+
+
+    % diff_out.write_command displays a diff(1) command.
+    % Like ed(1), a pair of numbers which are identical
+    % are abbreviated by a single number.
+    % MK: Assumption X=<X2
+    % AJB: And, similarly, Y=<Y2.  This is actually an
+    %      invariant of the segment type.  See difftype.m.
+:- pred diff_out.write_command(segment::in, char::in, segment::in,
+        io.state::di, io.state::uo) is det.
+
+diff_out.write_command(X - X2, C, Y - Y2, !IO) :-
+    X1 is X + 1,    % Convert from pos to line number
+    ( X1 >= X2 ->
+        % either empty or singleton segment
+        io.write_int(X2, !IO)
+    ;
+        io.write_int(X1, !IO),
+        io.write_char(',', !IO),
+        io.write_int(X2, !IO)
+    ),
+    io.write_char(C, !IO),
+    Y1 is Y + 1,    % Convert from pos to line number
+    ( Y1 >= Y2 ->
+        % either empty or singleton segment
+        io.write_int(Y2, !IO)
+    ;
+        io.write_int(Y1, !IO),
+        io.write_char(',', !IO),
+        io.write_int(Y2, !IO)
+    ),
+    io.write_char('\n', !IO).
+
+%-----------------------------------------------------------------------------%
+
+    % display_diff_rcs takes a diff and displays it
+    % in the RCS difference format.
+:- pred display_diff_rcs(file::in, file::in, diff::in,
+        io.state::di, io.state::uo) is det.
+
+display_diff_rcs(_File1, _File2, [], !IO).
+display_diff_rcs(File1, File2, [Cmd | Diff], !IO) :-
+    ( Cmd = add(X, Y1 - Y2),
+        diff_out.write_command_rcs('a', X, Y2-Y1, !IO),
+        diff_out.show_file(File2, "", Y1, Y2, !IO)
+    ; Cmd = delete(X1 - X2, _Y),
+        diff_out.write_command_rcs('d', X1, X2-X1, !IO)
+    ; Cmd = change(X1 - X2, Y1 - Y2),
+        diff_out.write_command_rcs('d', X1, X2-X1, !IO),
+        diff_out.write_command_rcs('a', X1, Y2-Y1, !IO),
+        diff_out.show_file(File2, "", Y1, Y2, !IO)
+    ),
+    display_diff_rcs(File1, File2, Diff, !IO).
+
+
+    % diff_out.write_command_rcs displays a diff command in
+    % the RCS ,v format.
+:- pred diff_out.write_command_rcs(char::in, int::in, int::in,
+        io.state::di, io.state::uo) is det.
+
+diff_out.write_command_rcs(C, X, Y, !IO) :-
+    io.write_char(C, !IO),
+    io.write_int(X + 1, !IO),   % Convert from pos to line number
+    io.write_char(' ', !IO),
+    io.write_int(Y, !IO),
+    io.write_char('\n', !IO).
+
+%-----------------------------------------------------------------------------%
+
+    % display_diff_ed takes a diff and displays it
+    % in ed(1) format, but with all diffs backward.
+:- pred display_diff_ed(file::in, file::in, diff::in,
+        io.state::di, io.state::uo) is det.
+
+display_diff_ed(_File1, _File2, [], !IO).
+display_diff_ed(File1, File2, [Cmd | Diff], !IO) :-
+    display_diff_ed(File1, File2, Diff, !IO),
+    ( Cmd = add(X, Y1 - Y2),
+        diff_out.write_command_ed(X - X, 'a', !IO),
+        diff_out.show_file(File2, "", Y1, Y2, !IO),
+        io.write_string(".\n", !IO)
+    ; Cmd = delete(X, _Y),
+        diff_out.write_command_ed(X, 'd', !IO)
+    ; Cmd = change(X, Y1 - Y2),
+        diff_out.write_command_ed(X, 'c', !IO),
+        diff_out.show_file(File2, "", Y1, Y2, !IO),
+        io.write_string(".\n", !IO)
+    ).
+
+
+    % diff_out.write_command_ed displays an ed(1) command.
+:- pred diff_out.write_command_ed(segment::in, char::in,
+        io.state::di, io.state::uo) is det.
+
+diff_out.write_command_ed(X - X2, C, !IO) :-
+    X1 is X + 1,        % Convert from pos to line number
+    ( X1 >= X2 ->
+        % either empty or singleton segment
+        io.write_int(X2, !IO)
+    ;
+        io.write_int(X1, !IO),
+        io.write_char(',', !IO),
+        io.write_int(X2, !IO)
+    ),
+    io.write_char(C, !IO),
+    io.write_char('\n', !IO).
+
+%-----------------------------------------------------------------------------%
+
+    % display_diff_forward_ed takes a diff and displays it
+    % in ed(1) format, but with all diff_out forward.  This
+    % is actually useless for feeding to ed(1), but nicer
+    % to read.
+:- pred display_diff_forward_ed(file::in, file::in, diff::in,
+        io.state::di, io.state::uo) is det.
+
+display_diff_forward_ed(_File1, _File2, [], !IO).
+display_diff_forward_ed(File1, File2, [Cmd | Diff], !IO) :-
+    ( Cmd = add(X, Y1 - Y2),
+        diff_out.write_command_forward_ed(X - X, 'a', !IO),
+        diff_out.show_file(File2, "", Y1, Y2, !IO),
+        io.write_string(".\n", !IO)
+    ; Cmd = delete(X, _Y),
+        diff_out.write_command_forward_ed(X, 'd', !IO)
+    ; Cmd = change(X, Y1 - Y2),
+        diff_out.write_command_forward_ed(X, 'c', !IO),
+        diff_out.show_file(File2, "", Y1, Y2, !IO),
+        io.write_string(".\n", !IO)
+    ),
+    display_diff_forward_ed(File1, File2, Diff, !IO).
+
+    % diff_out.write_command_forward_ed displays a forward ed(1)
+    % command.  The difference between this and write_command_ed is
+    % that the command char comes first here.  Who comes up with
+    % these dumb formats anyway?
+:- pred diff_out.write_command_forward_ed(segment::in, char::in,
+        io.state::di, io.state::uo) is det.
+diff_out.write_command_forward_ed(X - X2, C, !IO) :-
+    io.write_char(C, !IO),
+    X1 is X + 1,        % Convert from pos to line number
+    ( X1 >= X2 ->
+        % either empty or singleton segment
+        io.write_int(X2, !IO)
+    ;
+        io.write_int(X1, !IO),
+        io.write_char(' ', !IO),
+        io.write_int(X2, !IO)
+    ),
+    io.write_char('\n', !IO).
+
+%-----------------------------------------------------------------------------%
+%-----------------------------------------------------------------------------%
+
+    % display_diff_ifdef writes out the files in a unified diff,
+    % using #ifdefs around each edit.
+    %
+    % TO DO: GNU diff makes this output style much more
+    %        configurable.  We should too.
+:- pred display_diff_ifdef(string::in, file::in, file::in, diff::in,
+        io.state::di, io.state::uo) is det.
+
+display_diff_ifdef(Sym, File1, File2, Diff, !IO) :-
+    display_diff_ifdef_2(0, Sym, File1, File2, Diff, !IO).
+
+    % Argument 1 (prev) is the last pos displayed before
+    % the current edit (or end of edits, in the base case).
+    % This is important for when we have to display the
+    % "non-diffed" text between edits.
+:- pred display_diff_ifdef_2(int::in, string::in, file::in, file::in, diff::in,
+        io.state::di, io.state::uo) is det.
+
+display_diff_ifdef_2(Prev, _Sym, File1, _File2, [], !IO) :-
+    file.get_numlines(File1, SegEnd),
+    diff_out.show_file(File1, "", Prev, SegEnd, !IO).
+display_diff_ifdef_2(Prev, Sym, File1, File2, [Edit | Diff], !IO) :-
+    first_mentioned_positions(Edit, StartOfEdit, _),
+    diff_out.show_file(File1, "", Prev, StartOfEdit, !IO),
+    ( Edit = add(X, Y1 - Y2),
+        io.write_strings(["#ifdef ", Sym, "\n"], !IO),
+        diff_out.show_file(File2, "", Y1, Y2, !IO),
+        io.write_strings(["#endif /* ", Sym, " */\n"], !IO),
+        Next = X
+    ; Edit = delete(X1 - X2, _),
+        io.write_strings(["#ifndef ", Sym, "\n"], !IO),
+        diff_out.show_file(File1, "", X1, X2, !IO),
+        io.write_strings(["#endif /* not ", Sym, " */\n"], !IO),
+        Next = X2
+    ; Edit = change(X1 - X2, Y1 - Y2),
+        io.write_strings(["#ifndef ", Sym, "\n"], !IO),
+        diff_out.show_file(File1, "", X1, X2, !IO),
+        io.write_strings(["#else /* ", Sym, " */\n"], !IO),
+        diff_out.show_file(File2, "", Y1, Y2, !IO),
+        io.write_strings(["#endif /* ", Sym, " */\n"], !IO),
+        Next = X2
+    ),
+    display_diff_ifdef_2(Next, Sym, File1, File2, Diff, !IO).
+
+%-----------------------------------------------------------------------------%
+%-----------------------------------------------------------------------------%
+
+    % display_diff_cvs_merge_conflict writes out the files in a
+    % unified diff, using CVS merge conflict marks around each edit.
+    %
+:- pred display_diff_cvs_merge_conflict(file::in, file::in, diff::in,
+        io.state::di, io.state::uo) is det.
+
+display_diff_cvs_merge_conflict(File1, File2, Diff, !IO) :-
+    display_diff_cvs_merge_conflict_2(0, File1, File2, Diff, !IO).
+
+    % Argument 1 (prev) is the last pos displayed before
+    % the current edit (or end of edits, in the base case).
+    % This is important for when we have to display the
+    % "non-diffed" text between edits.
+:- pred display_diff_cvs_merge_conflict_2(int::in, file::in, file::in,
+        diff::in, io.state::di, io.state::uo) is det.
+
+display_diff_cvs_merge_conflict_2(Prev, File1, _File2, [], !IO) :-
+    file.get_numlines(File1, SegEnd),
+    diff_out.show_file(File1, "", Prev, SegEnd, !IO).
+display_diff_cvs_merge_conflict_2(Prev, File1, File2, [Edit | Diff], !IO) :-
+    first_mentioned_positions(Edit, StartOfEdit, _),
+    diff_out.show_file(File1, "", Prev, StartOfEdit, !IO),
+    file.get_file_name(File1, FileName1),
+    file.get_file_name(File2, FileName2),
+    ( Edit = add(X, Y1 - Y2),
+        io.write_strings(["<<<<<<< ", FileName1, "\n"], !IO),
+        diff_out.show_file(File2, "", Y1, Y2, !IO),
+        io.write_string("=======\n", !IO),
+        io.write_strings([">>>>>>> ", FileName2, "\n"], !IO),
+        Next = X
+    ; Edit = delete(X1 - X2, _),
+        io.write_strings(["<<<<<<< ", FileName1, "\n"], !IO),
+        io.write_string("=======\n", !IO),
+        diff_out.show_file(File1, "", X1, X2, !IO),
+        io.write_strings([">>>>>>> ", FileName2, "\n"], !IO),
+        Next = X2
+    ; Edit = change(X1 - X2, Y1 - Y2),
+        io.write_strings(["<<<<<<< ", FileName1, "\n"], !IO),
+        diff_out.show_file(File1, "", X1, X2, !IO),
+        io.write_string("=======\n", !IO),
+        diff_out.show_file(File2, "", Y1, Y2, !IO),
+        io.write_strings([">>>>>>> ", FileName2, "\n"], !IO),
+        Next = X2
+    ),
+    display_diff_cvs_merge_conflict_2(Next, File1, File2, Diff, !IO).
+
+%-----------------------------------------------------------------------------%
+%-----------------------------------------------------------------------------%
+
+    % Types for context/unified diffs.
+
+    % A context diff is a bit more complicated than a "standard"
+    % diff, because it requires the display of some parts of the
+    % files which are not actually part of the diff, but not all
+    % of it.
+    %
+    % Because context and unified diffs both require the same
+    % kind of information, we factor out the code to turn a
+    % normal diff into a context diff.

 :- type context_edit
-	--->	context_edit(segment, segment, diff).
+    --->    context_edit(segment, segment, diff).

 :- type context_diff == list(context_edit).

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

 :- pred diff_to_context_diff(int :: in, int :: in, int :: in, diff :: in,
-		context_diff :: out) is det.
+        context_diff :: out) is det.

 diff_to_context_diff(_Xsize, _Ysize, _Context, [], []).
 diff_to_context_diff(Xsize, Ysize, Context, [Edit | Diff], CDiff) :-
-	diff_to_context_diff(Xsize, Ysize, Context, Diff, CDiff0),
+    diff_to_context_diff(Xsize, Ysize, Context, Diff, CDiff0),

-		% Work out how far the context of this edit reaches.
-	first_mentioned_positions(Edit, Xfirst0, Yfirst0),
-	int__max(Xfirst0 - Context, 0, Xfirst),
-	int__max(Yfirst0 - Context, 0, Yfirst),
-	last_mentioned_positions(Edit, Xlast0, Ylast0),
-	int__min(Xlast0 + Context, Xsize, Xlast),
-	int__min(Ylast0 + Context, Ysize, Ylast),
-
-	( CDiff0 = [],
-		CDiff = [context_edit(Xfirst - Xlast, Yfirst - Ylast, [Edit])]
-	; CDiff0 = [context_edit(XsegLo - XsegHi, YsegLo - YsegHi, DDiff) |
-				CDiff1],
-		% Should we merge this edit into the next one?
-		(
-			( XsegLo =< Xlast
-			; YsegLo =< Ylast
-			)
-		->
-			CDiff = [context_edit(Xfirst - XsegHi, Yfirst - YsegHi,
-					[Edit | DDiff]) | CDiff1]
-		;
-			CDiff = [context_edit(Xfirst - Xlast, Yfirst - Ylast,
-					[Edit]) | CDiff0]
-		)
-	).
+        % Work out how far the context of this edit reaches.
+    first_mentioned_positions(Edit, Xfirst0, Yfirst0),
+    int.max(Xfirst0 - Context, 0, Xfirst),
+    int.max(Yfirst0 - Context, 0, Yfirst),
+    last_mentioned_positions(Edit, Xlast0, Ylast0),
+    int.min(Xlast0 + Context, Xsize, Xlast),
+    int.min(Ylast0 + Context, Ysize, Ylast),
+
+    ( CDiff0 = [],
+        CDiff = [context_edit(Xfirst - Xlast, Yfirst - Ylast, [Edit])]
+    ; CDiff0 = [context_edit(XsegLo - XsegHi, YsegLo - YsegHi, DDiff) |
+                CDiff1],
+        % Should we merge this edit into the next one?
+        (
+            ( XsegLo =< Xlast
+            ; YsegLo =< Ylast
+            )
+        ->
+            CDiff = [context_edit(Xfirst - XsegHi, Yfirst - YsegHi,
+                    [Edit | DDiff]) | CDiff1]
+        ;
+            CDiff = [context_edit(Xfirst - Xlast, Yfirst - Ylast,
+                    [Edit]) | CDiff0]
+        )
+    ).

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

-	% Display a diff in unified format.
-:- pred display_unified_diff(int, file, file, diff, io__state, io__state).
-:- mode display_unified_diff(in, in, in, in, di, uo) is det.
-
-display_unified_diff(Context, File1, File2, Diff) -->
-	{ file__get_numlines(File1, Size1) },
-	{ file__get_numlines(File2, Size2) },
-	{ diff_to_context_diff(Size1, Size2, Context, Diff, CDiff) },
-	{ file__get_file_name(File1, Name1) },
-	{ file__get_file_name(File2, Name2) },
-		% XXX Should also print out file dates.  But how?
-	io__write_strings(["--- ", Name1, "\n"]),
-	io__write_strings(["+++ ", Name2, "\n"]),
-	globals__io_lookup_bool_option(initial_tab, InitialTab),
-	{ InitialTab = no,
-		NoneStr = " ",
-		AddStr = "+",
-		DelStr = "-"
-	; InitialTab = yes,
-		NoneStr = "\t",
-		AddStr = "+\t",
-		DelStr = "-\t"
-	},
-	display_unified_diff_2(File1, File2, CDiff, NoneStr, AddStr, DelStr).
-
-:- pred display_unified_diff_2(file, file, context_diff, string,
string, string,
-				io__state, io__state).
-:- mode display_unified_diff_2(in, in, in, in, in, in, di, uo) is det.
+    % Display a diff in unified format.
+:- pred display_unified_diff(int::in, file::in, file::in, diff::in,
+        io.state::di, io.state::uo).
+
+display_unified_diff(Context, File1, File2, Diff, !IO) :-
+    file.get_numlines(File1, Size1),
+    file.get_numlines(File2, Size2),
+    diff_to_context_diff(Size1, Size2, Context, Diff, CDiff),
+    file.get_file_name(File1, Name1),
+    file.get_file_name(File2, Name2),
+        % XXX Should also print out file dates.  But how?
+    io.write_strings(["--- ", Name1, "\n"], !IO),
+    io.write_strings(["+++ ", Name2, "\n"], !IO),
+    globals.io_lookup_bool_option(initial_tab, InitialTab, !IO),
+    ( InitialTab = no,
+        NoneStr = " ",
+        AddStr = "+",
+        DelStr = "-"
+    ; InitialTab = yes,
+        NoneStr = "\t",
+        AddStr = "+\t",
+        DelStr = "-\t"
+    ),
+    display_unified_diff_2(File1, File2, CDiff, NoneStr, AddStr,
+            DelStr, !IO).
+
+:- pred display_unified_diff_2(file::in, file::in, context_diff::in,
+        string::in, string::in, string::in,
+        io.state::di, io.state::uo) is det.

-display_unified_diff_2(_File1, _File2, [], _, _, _) --> [].
+display_unified_diff_2(_File1, _File2, [], _, _, _, !IO).
 display_unified_diff_2(File1, File2, [Edit | CDiff],
-			NoneStr, AddStr, DelStr) -->
-	{ Edit = context_edit(Xlow - Xhigh, Ylow - Yhigh, Diff) },
-	io__format("@@ -%d,%d +%d,%d @@\n",
-		[i(Xlow + 1), i(Xhigh - Xlow), i(Ylow + 1), i(Yhigh - Ylow)]),
-	display_unified_diff_3(Xlow, Xhigh, File1, File2, Diff,
-			NoneStr, AddStr, DelStr),
-	display_unified_diff_2(File1, File2, CDiff, NoneStr, AddStr, DelStr).
-
-:- pred display_unified_diff_3(int, int, file, file, diff,
-				string, string, string, io__state, io__state).
-:- mode display_unified_diff_3(in, in, in, in, in, in, in, in, di, uo) is det.
+            NoneStr, AddStr, DelStr, !IO) :-
+    Edit = context_edit(Xlow - Xhigh, Ylow - Yhigh, Diff),
+    io.format("@@ -%d,%d +%d,%d @@\n",
+        [i(Xlow + 1), i(Xhigh - Xlow), i(Ylow + 1), i(Yhigh - Ylow)],
+        !IO),
+    display_unified_diff_3(Xlow, Xhigh, File1, File2, Diff,
+            NoneStr, AddStr, DelStr, !IO),
+    display_unified_diff_2(File1, File2, CDiff, NoneStr, AddStr,
+            DelStr, !IO).
+
+:- pred display_unified_diff_3(int::in, int::in, file::in, file::in, diff::in,
+    string::in, string::in, string::in, io.state::di, io.state::uo) is det.

-display_unified_diff_3(Prev, Size1, File1, _File2, [], NoneStr, _, _) -->
-	diff_out__show_file(File1, NoneStr, Prev, Size1).
+display_unified_diff_3(Prev, Size1, File1, _File2, [], NoneStr, _, _, !IO) :-
+    diff_out.show_file(File1, NoneStr, Prev, Size1, !IO).
 display_unified_diff_3(Prev, Size1, File1, File2, [Edit | Diff],
-			NoneStr, AddStr, DelStr) -->
-	{ first_mentioned_positions(Edit, StartOfEdit, _) },
-	diff_out__show_file(File1, NoneStr, Prev, StartOfEdit),
-	( { Edit = add(X, Y1 - Y2) },
-		diff_out__show_file(File2, AddStr, Y1, Y2),
-		{ Next = X }
-	; { Edit = delete(X1 - X2, _) },
-		diff_out__show_file(File1, DelStr, X1, X2),
-		{ Next = X1 }
-	; { Edit = change(X1 - X2, Y1 - Y2) },
-		diff_out__show_file(File1, DelStr, X1, X2),
-		diff_out__show_file(File2, AddStr, Y1, Y2),
-		{ Next = X1 }
-	),
-	display_unified_diff_3(Next, Size1, File1, File2, Diff,
-				NoneStr, AddStr, DelStr).
+            NoneStr, AddStr, DelStr, !IO) :-
+    first_mentioned_positions(Edit, StartOfEdit, _),
+    diff_out.show_file(File1, NoneStr, Prev, StartOfEdit, !IO),
+    ( Edit = add(X, Y1 - Y2),
+        diff_out.show_file(File2, AddStr, Y1, Y2, !IO),
+        Next = X
+    ; Edit = delete(X1 - X2, _),
+        diff_out.show_file(File1, DelStr, X1, X2, !IO),
+        Next = X1
+    ; Edit = change(X1 - X2, Y1 - Y2),
+        diff_out.show_file(File1, DelStr, X1, X2, !IO),
+        diff_out.show_file(File2, AddStr, Y1, Y2, !IO),
+        Next = X1
+    ),
+    display_unified_diff_3(Next, Size1, File1, File2, Diff,
+                NoneStr, AddStr, DelStr, !IO).

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

-	% Display a diff in context format.
-:- pred display_context_diff(int, file, file, diff, io__state, io__state).
-:- mode display_context_diff(in, in, in, in, di, uo) is det.
-
-display_context_diff(Context, File1, File2, Diff) -->
-	{ file__get_numlines(File1, Size1) },
-	{ file__get_numlines(File2, Size2) },
-	{ diff_to_context_diff(Size1, Size2, Context, Diff, CDiff) },
-	{ file__get_file_name(File1, Name1) },
-	{ file__get_file_name(File2, Name2) },
-		% XXX Should also print out file dates.  But how??
-	io__write_strings(["*** ", Name1, "\n"]),
-	io__write_strings(["--- ", Name2, "\n"]),
-
-	globals__io_lookup_bool_option(initial_tab, InitialTab),
-	{ InitialTab = no,
-		NoneStr = "  ",
-		AddStr = "+ ",
-		DelStr = "- ",
-		ChgStr = "! "
-	; InitialTab = yes,
-		NoneStr = "\t",
-		AddStr = "+\t",
-		DelStr = "-\t",
-		ChgStr = "!\t"
-	},
-	display_context_diff_2(File1, File2, CDiff,
-			NoneStr, AddStr, DelStr, ChgStr).
-
-:- pred display_context_diff_2(file, file, context_diff,
-		string, string, string, string, io__state, io__state).
-:- mode display_context_diff_2(in, in, in, in, in, in, in, di, uo) is det.
+    % Display a diff in context format.
+:- pred display_context_diff(int::in, file::in, file::in, diff::in,
+        io.state::di, io.state::uo) is det.
+
+display_context_diff(Context, File1, File2, Diff, !IO) :-
+    file.get_numlines(File1, Size1),
+    file.get_numlines(File2, Size2),
+    diff_to_context_diff(Size1, Size2, Context, Diff, CDiff),
+    file.get_file_name(File1, Name1),
+    file.get_file_name(File2, Name2),
+        % XXX Should also print out file dates.  But how??
+    io.write_strings(["*** ", Name1, "\n"], !IO),
+    io.write_strings(["--- ", Name2, "\n"], !IO),
+
+    globals.io_lookup_bool_option(initial_tab, InitialTab, !IO),
+    ( InitialTab = no,
+        NoneStr = "  ",
+        AddStr = "+ ",
+        DelStr = "- ",
+        ChgStr = "! "
+    ; InitialTab = yes,
+        NoneStr = "\t",
+        AddStr = "+\t",
+        DelStr = "-\t",
+        ChgStr = "!\t"
+    ),
+    display_context_diff_2(File1, File2, CDiff,
+            NoneStr, AddStr, DelStr, ChgStr, !IO).
+
+:- pred display_context_diff_2(file::in, file::in, context_diff::in,
+        string::in, string::in, string::in, string::in,
+        io.state::di, io.state::uo) is det.

-display_context_diff_2(_File1, _File2, [], _, _, _, _) --> [].
+display_context_diff_2(_File1, _File2, [], _, _, _, _, !IO).
 display_context_diff_2(File1, File2, [Edit | CDiff],
-		NoneStr, AddStr, DelStr, ChgStr) -->
-	{ Edit = context_edit(Xlow - Xhigh, Ylow - Yhigh, Diff) },
-	io__write_string("***************\n"),
-	io__format("*** %d,%d ****\n", [i(Xlow + 1), i(Xhigh)]),
-
-		% Don't display the "context from" lines if there's
-		% nothing deleted or changed.
-	( { all [AEdit] list__member(AEdit, Diff) => AEdit = add(_, _) } ->
-		[]
-	;
-		display_context_diff_left(Xlow, Xhigh, File1, Diff,
-				NoneStr, DelStr, ChgStr)
-	),
-	io__format("--- %d,%d ----\n", [i(Ylow + 1), i(Yhigh)]),
-
-		% Don't display the "context to" lines if there's
-		% nothing added or changed.
-	( { all [DEdit] list__member(DEdit, Diff) => DEdit = delete(_, _) } ->
-		[]
-	;
-		display_context_diff_right(Ylow, Yhigh, File2, Diff,
-				NoneStr, AddStr, ChgStr)
-	),
-	display_context_diff_2(File1, File2, CDiff,
-			NoneStr, AddStr, DelStr, ChgStr).
-
-:- pred display_context_diff_left(int, int, file, diff, string, string, string,
-			io__state, io__state).
-:- mode display_context_diff_left(in, in, in, in, in, in, in, di, uo) is det.
+        NoneStr, AddStr, DelStr, ChgStr, !IO) :-
+    Edit = context_edit(Xlow - Xhigh, Ylow - Yhigh, Diff),
+    io.write_string("***************\n", !IO),
+    io.format("*** %d,%d ****\n", [i(Xlow + 1), i(Xhigh)], !IO),
+
+        % Don't display the "context from" lines if there's
+        % nothing deleted or changed.
+    ( all [AEdit] list.member(AEdit, Diff) => AEdit = add(_, _) ->
+        true
+    ;
+        display_context_diff_left(Xlow, Xhigh, File1, Diff,
+                NoneStr, DelStr, ChgStr, !IO)
+    ),
+    io.format("--- %d,%d ----\n", [i(Ylow + 1), i(Yhigh)], !IO),
+
+        % Don't display the "context to" lines if there's
+        % nothing added or changed.
+    ( all [DEdit] list.member(DEdit, Diff) => DEdit = delete(_, _) ->
+        true
+    ;
+        display_context_diff_right(Ylow, Yhigh, File2, Diff,
+                NoneStr, AddStr, ChgStr, !IO)
+    ),
+    display_context_diff_2(File1, File2, CDiff,
+            NoneStr, AddStr, DelStr, ChgStr, !IO).
+
+:- pred display_context_diff_left(int::in, int::in, file::in, diff::in,
+        string::in, string::in, string::in,
+        io.state::di, io.state::uo) is det.

-display_context_diff_left(Prev, Size1, File1, [], NoneStr, _, _) -->
-	diff_out__show_file(File1, NoneStr, Prev, Size1).
+display_context_diff_left(Prev, Size1, File1, [], NoneStr, _, _, !IO) :-
+    diff_out.show_file(File1, NoneStr, Prev, Size1, !IO).
 display_context_diff_left(Prev, Size1, File1, [Edit | Diff],
-			NoneStr, DelStr, ChgStr) -->
-	{ first_mentioned_positions(Edit, StartOfEdit, _) },
-	diff_out__show_file(File1, NoneStr, Prev, StartOfEdit),
-	( { Edit = add(X, _) },
-		{ Next = X }
-	; { Edit = delete(X1 - X2, _) },
-		diff_out__show_file(File1, DelStr, X1, X2),
-		{ Next = X2 }
-	; { Edit = change(X1 - X2, _) },
-		diff_out__show_file(File1, ChgStr, X1, X2),
-		{ Next = X2 }
-	),
-	display_context_diff_left(Next, Size1, File1, Diff,
-			NoneStr, DelStr, ChgStr).
-
-:- pred display_context_diff_right(int, int, file, diff,
-			string, string, string, io__state, io__state).
-:- mode display_context_diff_right(in, in, in, in, in, in, in, di, uo) is det.
+            NoneStr, DelStr, ChgStr, !IO) :-
+    first_mentioned_positions(Edit, StartOfEdit, _),
+    diff_out.show_file(File1, NoneStr, Prev, StartOfEdit, !IO),
+    ( Edit = add(X, _),
+        Next = X
+    ; Edit = delete(X1 - X2, _),
+        diff_out.show_file(File1, DelStr, X1, X2, !IO),
+        Next = X2
+    ; Edit = change(X1 - X2, _),
+        diff_out.show_file(File1, ChgStr, X1, X2, !IO),
+        Next = X2
+    ),
+    display_context_diff_left(Next, Size1, File1, Diff,
+            NoneStr, DelStr, ChgStr, !IO).
+
+:- pred display_context_diff_right(int::in, int::in, file::in, diff::in,
+        string::in, string::in, string::in,
+        io.state::di, io.state::uo) is det.

-display_context_diff_right(Prev, Size2, File2, [], NoneStr, _, _) -->
-	diff_out__show_file(File2, NoneStr, Prev, Size2).
+display_context_diff_right(Prev, Size2, File2, [], NoneStr, _, _, !IO) :-
+    diff_out.show_file(File2, NoneStr, Prev, Size2, !IO).
 display_context_diff_right(Prev, Size2, File2, [Edit | Diff],
-			NoneStr, AddStr, ChgStr) -->
-	{ first_mentioned_positions(Edit, StartOfEdit, _) },
-	diff_out__show_file(File2, NoneStr, Prev, StartOfEdit),
-	( { Edit = add(_, Y1 - Y2) },
-		diff_out__show_file(File2, AddStr, Y1, Y2),
-		{ Next = Y2 }
-	; { Edit = delete(_, Y) },
-		{ Next = Y }
-	; { Edit = change(_, Y1 - Y2) },
-		diff_out__show_file(File2, ChgStr, Y1, Y2),
-		{ Next = Y2 }
-	),
-	display_context_diff_right(Next, Size2, File2, Diff,
-				NoneStr, AddStr, ChgStr).
+            NoneStr, AddStr, ChgStr, !IO) :-
+    first_mentioned_positions(Edit, StartOfEdit, _),
+    diff_out.show_file(File2, NoneStr, Prev, StartOfEdit, !IO),
+    ( Edit = add(_, Y1 - Y2),
+        diff_out.show_file(File2, AddStr, Y1, Y2, !IO),
+        Next = Y2
+    ; Edit = delete(_, Y),
+        Next = Y
+    ; Edit = change(_, Y1 - Y2),
+        diff_out.show_file(File2, ChgStr, Y1, Y2, !IO),
+        Next = Y2
+    ),
+    display_context_diff_right(Next, Size2, File2, Diff,
+                NoneStr, AddStr, ChgStr, !IO).

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

-	% Side-by-side diffs are incredibly complex, as you'll see if
-	% you inspect the code below.
-	%
-	% TO DO: GNU diff has --sdiff-merge-assist, but I can find no
-	%        documentation on what this actually does, and haven't
-	%        had the time to investigate.  For the moment, we accept
-	%        the option and note here whether or not it's turned on,
-	%        but do nothing with it.
+    % Side-by-side diffs are incredibly complex, as you'll see if
+    % you inspect the code below.
+    %
+    % TO DO: GNU diff has --sdiff-merge-assist, but I can find no
+    %        documentation on what this actually does, and haven't
+    %        had the time to investigate.  For the moment, we accept
+    %        the option and note here whether or not it's turned on,
+    %        but do nothing with it.

-	% Parameters to pass around.
+    % Parameters to pass around.
 :- type side_by_side_info
-	--->	side_by_side_info(
-			int,		% Half width
-			int,		% Column 2 offset
-			bool,		% Left column only
-			bool,		% Suppress common lines
-			bool		% Help sdiff
-		).
-
-:- pred display_diff_side_by_side(file, file, diff, io__state, io__state).
-:- mode display_diff_side_by_side(in, in, in, di, uo) is det.
-
-display_diff_side_by_side(File1, File2, Diff) -->
-	globals__io_lookup_int_option(width, Width0),
-
-	% Calculate the half-width and offset stuff.
-
-		% XXX If we're expanding tabs, we should
-		%     factor this in.
-	{ Off is (Width0 + 4) // 8 * 4 },
-	{ Max is Off - 3 },
-	{ HalfWidth0 is Width0 - Off + 1 },
-	{ HalfWidth0 =< 0 ->
-		HalfWidth = 0
-	; HalfWidth0 > Max ->
-		HalfWidth = Max
-	;
-		HalfWidth = HalfWidth0
-	},
-	{ HalfWidth > 0 ->
-		Col2Off = Off
-	;
-		Col2Off = Width0
-	},
-	globals__io_lookup_bool_option(left_column, LeftCol),
-	globals__io_lookup_bool_option(suppress_common_lines, Suppress),
-	globals__io_lookup_bool_option(sdiff_merge_assist, Sdiff),
-	{ SBS = side_by_side_info(HalfWidth, Col2Off, LeftCol,
-		Suppress, Sdiff) },
-	display_diff_side_by_side_2(0, SBS, File1, File2, Diff).
-
-:- pred display_diff_side_by_side_2(int, side_by_side_info, file, file, diff,
-		io__state, io__state).
-:- mode display_diff_side_by_side_2(in, in, in, in, in, di, uo) is det.
-
-display_diff_side_by_side_2(Prev, SBS, File1, _File2, []) -->
-	{ SBS = side_by_side_info(_, _, _, Suppress, _) },
-	( { Suppress = no } ->
-		{ file__get_numlines(File1, SegEnd) },
-		show_sbs_same_lines(File1, SBS, Prev - SegEnd)
-	;
-		[]
-	).
-display_diff_side_by_side_2(Prev, SBS, File1, File2, [Edit | Diff]) -->
-	{ SBS = side_by_side_info(_, _, _, Suppress, _) },
-	{ first_mentioned_positions(Edit, StartOfEdit, _) },
-	( { Suppress = no } ->
-		show_sbs_same_lines(File1, SBS, Prev - StartOfEdit)
-	;
-		[]
-	),
-	( { Edit = add(X, Seg2) },
-		show_sbs_added_lines(File2, SBS, Seg2),
-		{ Next = X }
-	; { Edit = delete(X1 - X2, _) },
-		show_sbs_deleted_lines(File1, SBS, X1 - X2),
-		{ Next = X2 }
-	; { Edit = change(X1 - X2, Y1 - Y2) },
-		% The side-by-side change diff format is sort of weird.
-		% We have to compute the minimum of the two change sizes,
-		% and display "changed" lines for the minimum of these
-		% sizes.  Then we display "added" or "deleted" lines for
-		% whatever is left over.
-		{ int__min(X2 - X1, Y2 - Y1, Size) },
-		show_sbs_changed_lines(File1, File2, SBS, X1, Y1, Size),
-		show_sbs_deleted_lines(File1, SBS, (X1 + Size) - X2),
-		show_sbs_added_lines(File2, SBS, (Y1 + Size) - Y2),
-		{ Next = X2 }
-	),
-	display_diff_side_by_side_2(Next, SBS, File1, File2, Diff).
-
-:- pred show_sbs_changed_lines(file, file, side_by_side_info, int, int, int,
-		io__state, io__state).
-:- mode show_sbs_changed_lines(in, in, in, in, in, in, di, uo) is det.
-
-show_sbs_changed_lines(File1, File2, SBS, X1, Y1, Size) -->
-	( { Size > 0 } ->
-		(
-			{ file__get_line(File1, X1, Line1),
-			  file__get_line(File2, Y1, Line2)
-			}
-		->
-			{ SBS = side_by_side_info(Width, _, _, _, _) },
-			{ string__to_char_list(Line1, Chars1) },
-			print_half_line(Chars1, SBS, 0, 0, Width, OutPos),
-			tab_to_column(OutPos, Width),
-			io__write_string("|"),
-			tab_to_column(Width + 1, Width + 2),
-			{ string__to_char_list(Line2, Chars2) },
-			print_half_line(Chars2, SBS, 0, 0, Width, _),
-			io__write_string("\n"),
-			show_sbs_changed_lines(File1, File2, SBS,
-					X1 + 1, Y1 + 1, Size - 1)
-		;
-			{ error("show_sbs_changed_lines: file ended prematurely") }
-		)
-	;
-		[]
-	).
-
-:- pred show_sbs_same_lines(file, side_by_side_info, segment,
-		io__state, io__state).
-:- mode show_sbs_same_lines(in, in, in, di, uo) is det.
-
-show_sbs_same_lines(File, SBS, Low - High) -->
-	( { Low < High } ->
-		( { file__get_line(File, Low, Line) } ->
-			{ SBS = side_by_side_info(Width, _, LeftCol, _, _) },
-			{ string__to_char_list(Line, Chars) },
-			print_half_line(Chars, SBS, 0, 0, Width, OutPos),
-
-			% If the user specified --left, don't
-			% display the right column here.
-			( { LeftCol = yes } ->
-				tab_to_column(OutPos, Width),
-				io__write_string("(")
-			;
-				tab_to_column(OutPos, Width + 2),
-				print_half_line(Chars, SBS, 0, 0, Width, _)
-			),
-			io__write_string("\n"),
-			show_sbs_same_lines(File, SBS, (Low + 1) - High)
-		;
-			{ error("show_sbs_same_lines: file ended prematurely") }
-		)
-	;
-		[]
-	).
-
-:- pred show_sbs_added_lines(file, side_by_side_info, segment,
-		io__state, io__state).
-:- mode show_sbs_added_lines(in, in, in, di, uo) is det.
-
-show_sbs_added_lines(File, SBS, Low - High) -->
-	( { Low < High } ->
-		( { file__get_line(File, Low, Line) } ->
-			{ SBS = side_by_side_info(Width, _, _, _, _) },
-			{ string__to_char_list(Line, Chars) },
-			tab_to_column(0, Width),
-			io__write_string("> "),
-			print_half_line(Chars, SBS, 0, 0, Width, _),
-			io__write_string("\n"),
-			show_sbs_added_lines(File, SBS, (Low + 1) - High)
-		;
-			{ error("show_sbs_added_lines: file ended prematurely") }
-		)
-	;
-		[]
-	).
-
-:- pred show_sbs_deleted_lines(file, side_by_side_info, segment,
-		io__state, io__state).
-:- mode show_sbs_deleted_lines(in, in, in, di, uo) is det.
-
-show_sbs_deleted_lines(File, SBS, Low - High) -->
-	( { Low < High } ->
-		( { file__get_line(File, Low, Line) } ->
-			{ SBS = side_by_side_info(Width, _, _, _, _) },
-			{ string__to_char_list(Line, Chars) },
-			print_half_line(Chars, SBS, 0, 0, Width, OutPos),
-			tab_to_column(OutPos, Width),
-			io__write_string("<\n"),
-			show_sbs_deleted_lines(File, SBS, (Low + 1) - High)
-		;
-			{ error("show_sbs_deleted_lines: file ended prematurely") }
-		)
-	;
-		[]
-	).
+    --->    side_by_side_info(
+            int,        % Half width
+            int,        % Column 2 offset
+            bool,       % Left column only
+            bool,       % Suppress common lines
+            bool        % Help sdiff
+        ).
+
+:- pred display_diff_side_by_side(file::in, file::in, diff::in,
+        io.state::di, io.state::uo) is det.
+
+display_diff_side_by_side(File1, File2, Diff, !IO) :-
+    globals.io_lookup_int_option(width, Width0, !IO),
+
+    % Calculate the half-width and offset stuff.
+
+        % XXX If we're expanding tabs, we should
+        %     factor this in.
+    Off is (Width0 + 4) // 8 * 4,
+    Max is Off - 3,
+    HalfWidth0 is Width0 - Off + 1,
+    ( HalfWidth0 =< 0 ->
+        HalfWidth = 0
+    ; HalfWidth0 > Max ->
+        HalfWidth = Max
+    ;
+        HalfWidth = HalfWidth0
+    ),
+    ( HalfWidth > 0 ->
+        Col2Off = Off
+    ;
+        Col2Off = Width0
+    ),
+    globals.io_lookup_bool_option(left_column, LeftCol, !IO),
+    globals.io_lookup_bool_option(suppress_common_lines, Suppress, !IO),
+    globals.io_lookup_bool_option(sdiff_merge_assist, Sdiff, !IO),
+    SBS = side_by_side_info(HalfWidth, Col2Off, LeftCol,
+        Suppress, Sdiff),
+    display_diff_side_by_side_2(0, SBS, File1, File2, Diff, !IO).
+
+:- pred display_diff_side_by_side_2(int::in, side_by_side_info::in, file::in,
+        file::in, diff::in, io.state::di, io.state::uo) is det.
+
+display_diff_side_by_side_2(Prev, SBS, File1, _File2, [], !IO) :-
+    SBS = side_by_side_info(_, _, _, Suppress, _),
+    ( Suppress = no ->
+        file.get_numlines(File1, SegEnd),
+        show_sbs_same_lines(File1, SBS, Prev - SegEnd, !IO)
+    ;
+        true
+    ).
+display_diff_side_by_side_2(Prev, SBS, File1, File2, [Edit | Diff], !IO) :-
+    SBS = side_by_side_info(_, _, _, Suppress, _),
+    first_mentioned_positions(Edit, StartOfEdit, _),
+    ( Suppress = no ->
+        show_sbs_same_lines(File1, SBS, Prev - StartOfEdit, !IO)
+    ;
+        true
+    ),
+    ( Edit = add(X, Seg2),
+        show_sbs_added_lines(File2, SBS, Seg2, !IO),
+        Next = X
+    ; Edit = delete(X1 - X2, _),
+        show_sbs_deleted_lines(File1, SBS, X1 - X2, !IO),
+        Next = X2
+    ; Edit = change(X1 - X2, Y1 - Y2),
+        % The side-by-side change diff format is sort of weird.
+        % We have to compute the minimum of the two change sizes,
+        % and display "changed" lines for the minimum of these
+        % sizes.  Then we display "added" or "deleted" lines for
+        % whatever is left over.
+        int.min(X2 - X1, Y2 - Y1, Size),
+        show_sbs_changed_lines(File1, File2, SBS, X1, Y1, Size, !IO),
+        show_sbs_deleted_lines(File1, SBS, (X1 + Size) - X2, !IO),
+        show_sbs_added_lines(File2, SBS, (Y1 + Size) - Y2, !IO),
+        Next = X2
+    ),
+    display_diff_side_by_side_2(Next, SBS, File1, File2, Diff, !IO).
+
+:- pred show_sbs_changed_lines(file::in, file::in, side_by_side_info::in,
+        int::in, int::in, int::in, io.state::di, io.state::uo) is det.
+
+show_sbs_changed_lines(File1, File2, SBS, X1, Y1, Size, !IO) :-
+    ( Size > 0 ->
+        (
+            file.get_line(File1, X1, Line1),
+              file.get_line(File2, Y1, Line2)
+        ->
+            SBS = side_by_side_info(Width, _, _, _, _),
+            string.to_char_list(Line1, Chars1),
+            print_half_line(Chars1, SBS, 0, 0, Width, OutPos, !IO),
+            tab_to_column(OutPos, Width, !IO),
+            io.write_string("|", !IO),
+            tab_to_column(Width + 1, Width + 2, !IO),
+            string.to_char_list(Line2, Chars2),
+            print_half_line(Chars2, SBS, 0, 0, Width, _, !IO),
+            io.write_string("\n", !IO),
+            show_sbs_changed_lines(File1, File2, SBS,
+                    X1 + 1, Y1 + 1, Size - 1, !IO)
+        ;
+            error("show_sbs_changed_lines: file ended prematurely")
+        )
+    ;
+        true
+    ).
+
+:- pred show_sbs_same_lines(file::in, side_by_side_info::in, segment::in,
+        io.state::di, io.state::uo) is det.
+
+show_sbs_same_lines(File, SBS, Low - High, !IO) :-
+    ( Low < High ->
+        ( file.get_line(File, Low, Line) ->
+            SBS = side_by_side_info(Width, _, LeftCol, _, _),
+            string.to_char_list(Line, Chars),
+            print_half_line(Chars, SBS, 0, 0, Width, OutPos, !IO),
+
+            % If the user specified --left, don't
+            % display the right column here.
+            ( LeftCol = yes ->
+                tab_to_column(OutPos, Width, !IO),
+                io.write_string("(", !IO)
+            ;
+                tab_to_column(OutPos, Width + 2, !IO),
+                print_half_line(Chars, SBS, 0, 0, Width, _, !IO)
+            ),
+            io.write_string("\n", !IO),
+            show_sbs_same_lines(File, SBS, (Low + 1) - High, !IO)
+        ;
+            error("show_sbs_same_lines: file ended prematurely")
+        )
+    ;
+        true
+    ).
+
+:- pred show_sbs_added_lines(file::in, side_by_side_info::in, segment::in,
+        io.state::di, io.state::uo) is det.
+
+show_sbs_added_lines(File, SBS, Low - High, !IO) :-
+    ( Low < High ->
+        ( file.get_line(File, Low, Line) ->
+            SBS = side_by_side_info(Width, _, _, _, _),
+            string.to_char_list(Line, Chars),
+            tab_to_column(0, Width, !IO),
+            io.write_string("> ", !IO),
+            print_half_line(Chars, SBS, 0, 0, Width, _, !IO),
+            io.write_string("\n", !IO),
+            show_sbs_added_lines(File, SBS, (Low + 1) - High, !IO)
+        ;
+            error("show_sbs_added_lines: file ended prematurely")
+        )
+    ;
+        true
+    ).
+
+:- pred show_sbs_deleted_lines(file::in, side_by_side_info::in, segment::in,
+        io.state::di, io.state::uo) is det.
+
+show_sbs_deleted_lines(File, SBS, Low - High, !IO) :-
+    ( Low < High ->
+        ( file.get_line(File, Low, Line) ->
+            SBS = side_by_side_info(Width, _, _, _, _),
+            string.to_char_list(Line, Chars),
+            print_half_line(Chars, SBS, 0, 0, Width, OutPos, !IO),
+            tab_to_column(OutPos, Width, !IO),
+            io.write_string("<\n", !IO),
+            show_sbs_deleted_lines(File, SBS, (Low + 1) - High, !IO)
+        ;
+            error("show_sbs_deleted_lines: file ended prematurely")
+        )
+    ;
+        true
+    ).

 :- func tab_width = int.
 tab_width = 8.

-	% Put a number of spaces on the output stream.  Update
-	% the output column as we go.
-:- pred put_spaces(int, int, int, io__state, io__state).
-:- mode put_spaces(in, in, out, di, uo) is det.
-
-put_spaces(Spaces, OutPos0, OutPos) -->
-	( { Spaces =< 0 } ->
-		{ OutPos = OutPos0 }
-	;
-		io__write_char(' '),
-		put_spaces(Spaces - 1, OutPos0 + 1, OutPos)
-	).
-
-	% Given a "from" column and a "to" column, put sufficient
-	% spaces on the output stream to reach that column.  Use
-	% tabs if we can.
-:- pred tab_to_column(int, int, io__state, io__state).
-:- mode tab_to_column(in, in, di, uo) is det.
-
-tab_to_column(From, To) -->
-	{ AfterTab is From + tab_width - (From rem tab_width) },
-	( { AfterTab > To } ->
-		( { From < To } ->
-			io__write_char(' '),
-			tab_to_column(From + 1, To)
-		;
-			[]
-		)
-	;
-		io__write_char('\t'),
-		tab_to_column(AfterTab, To)
-	).
-
-	% Display half a line in a side-by-side diff, stopping when
-	% we reach a certain column.
-	%
-	% This is actually a very simple thing to do, except for one
-	% complication, which is the displaying of tab characters.
-	%
-	% The important variables are:
-	%
-	%	InPos: The current column in the input line.
-	%	OutPos: The current column in the output line.
-	%	OutBound: The column that we must stop at.
-	%
+    % Put a number of spaces on the output stream.  Update
+    % the output column as we go.
+:- pred put_spaces(int::in, int::in, int::out, io.state::di,
io.state::uo) is det.
+
+put_spaces(Spaces, OutPos0, OutPos, !IO) :-
+    ( Spaces =< 0 ->
+        OutPos = OutPos0
+    ;
+        io.write_char(' ', !IO),
+        put_spaces(Spaces - 1, OutPos0 + 1, OutPos, !IO)
+    ).
+
+    % Given a "from" column and a "to" column, put sufficient
+    % spaces on the output stream to reach that column.  Use
+    % tabs if we can.
+:- pred tab_to_column(int::in, int::in, io.state::di, io.state::uo) is det.
+
+tab_to_column(From, To, !IO) :-
+    AfterTab is From + tab_width - (From rem tab_width),
+    ( AfterTab > To ->
+        ( From < To ->
+            io.write_char(' ', !IO),
+            tab_to_column(From + 1, To, !IO)
+        ;
+            true
+        )
+    ;
+        io.write_char('\t', !IO),
+        tab_to_column(AfterTab, To, !IO)
+    ).
+
+    % Display half a line in a side-by-side diff, stopping when
+    % we reach a certain column.
+    %
+    % This is actually a very simple thing to do, except for one
+    % complication, which is the displaying of tab characters.
+    %
+    % The important variables are:
+    %
+    %   InPos: The current column in the input line.
+    %   OutPos: The current column in the output line.
+    %   OutBound: The column that we must stop at.
+    %
 :- pred print_half_line(list(char) :: in, side_by_side_info :: in,
-		int :: in, int :: in, int :: in, int :: out,
-		io__state :: di, io__state :: uo) is det.
+        int :: in, int :: in, int :: in, int :: out,
+        io.state :: di, io.state :: uo) is det.

 print_half_line([], _SBS, _InPos, OutPos, _OutBound, OutPos) --> [].
 print_half_line([C | Cs], SBS, InPos0, OutPos0, OutBound, OutPos) -->
-	( { C = '\t' } ->
-			% Calculate how many spaces this tab is worth.
-		{ Spaces is tab_width - InPos0 rem tab_width },
-		( { InPos0 = OutPos0 } ->
-			globals__io_lookup_bool_option(expand_tabs, ExpandTabs),
-			( { ExpandTabs = yes } ->
-				% If we're expanding tabs, we just pretend that
-				% we had Spaces spaces and write them.
-				{ TabStop0 is OutPos0 + Spaces },
-				{ TabStop0 > OutBound ->
-					TabStop = OutBound
-				;
-					TabStop = TabStop0
-				},
-				put_spaces(TabStop - OutPos0, OutPos0, OutPos1)
-			;
-				% If we're not exanding tabs, just print it and
-				% hope everything lines up okay.
-				io__write_char('\t'),
-				{ OutPos1 is OutPos0 + Spaces }
-			)
-		;
-			{ OutPos1 = OutPos0 }
-		),
-		{ InPos is InPos0 + Spaces }
-	; { C = '\r' ; C = '\b' ; C = '\n' } ->
-		% XXX What to do?  For the moment, we'll just ignore it.
-		{ InPos = InPos0, OutPos1 = OutPos0 }
-	/***********
-		% XXX Binary files aren't really supported.
-	; { \+ char__is_print(C) } ->
-		{ InPos = InPos0, OutPos1 = OutPos0 }
-		( { InPos < OutBound } ->
-			io__write_char(C)
-		;
-			[]
-		)
-	***********/
-	;
-		% The default case.  Print and be done with it.
-		{ InPos is InPos0 + 1 },
-		( { InPos < OutBound } ->
-			{ OutPos1 = InPos },
-			io__write_char(C)
-		;
-			{ OutPos1 = OutPos0 }
-		)
-	),
-	print_half_line(Cs, SBS, InPos, OutPos1, OutBound, OutPos).
+    ( { C = '\t' } ->
+            % Calculate how many spaces this tab is worth.
+        { Spaces is tab_width - InPos0 rem tab_width },
+        ( { InPos0 = OutPos0 } ->
+            globals.io_lookup_bool_option(expand_tabs, ExpandTabs),
+            ( { ExpandTabs = yes } ->
+                % If we're expanding tabs, we just pretend that
+                % we had Spaces spaces and write them.
+                { TabStop0 is OutPos0 + Spaces },
+                { TabStop0 > OutBound ->
+                    TabStop = OutBound
+                ;
+                    TabStop = TabStop0
+                },
+                put_spaces(TabStop - OutPos0, OutPos0, OutPos1)
+            ;
+                % If we're not exanding tabs, just print it and
+                % hope everything lines up okay.
+                io.write_char('\t'),
+                { OutPos1 is OutPos0 + Spaces }
+            )
+        ;
+            { OutPos1 = OutPos0 }
+        ),
+        { InPos is InPos0 + Spaces }
+    ; { C = '\r' ; C = '\b' ; C = '\n' } ->
+        % XXX What to do?  For the moment, we'll just ignore it.
+        { InPos = InPos0, OutPos1 = OutPos0 }
+    /***********
+        % XXX Binary files aren't really supported.
+    ; { \+ char.is_print(C) } ->
+        { InPos = InPos0, OutPos1 = OutPos0 }
+        ( { InPos < OutBound } ->
+            io.write_char(C)
+        ;
+            []
+        )
+    ***********/
+    ;
+        % The default case.  Print and be done with it.
+        { InPos is InPos0 + 1 },
+        ( { InPos < OutBound } ->
+            { OutPos1 = InPos },
+            io.write_char(C)
+        ;
+            { OutPos1 = OutPos0 }
+        )
+    ),
+    print_half_line(Cs, SBS, InPos, OutPos1, OutBound, OutPos).

 %-----------------------------------------------------------------------------%
 %-----------------------------------------------------------------------------%
Index: samples/diff/difftype.m
===================================================================
RCS file: /home/mercury1/repository/mercury/samples/diff/difftype.m,v
retrieving revision 1.2
diff -u -r1.2 difftype.m
--- samples/diff/difftype.m	15 Sep 1998 04:54:24 -0000	1.2
+++ samples/diff/difftype.m	24 Apr 2006 05:48:16 -0000
@@ -1,4 +1,6 @@
 %-----------------------------------------------------------------------------%
+% vim: ft=mercury ts=4 sw=4 et
+%-----------------------------------------------------------------------------%
 % Copyright (C) 1995-1998 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.
@@ -17,32 +19,32 @@
 :- interface.
 :- import_module std_util, list.

-	% A pos is a non-negative number representing a position in a
-	% list.  The position before all elements is 0, the one
-	% between the first and second elements is 1, etc.
+    % A pos is a non-negative number representing a position in a
+    % list.  The position before all elements is 0, the one
+    % between the first and second elements is 1, etc.
 :- type pos == int.

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

-	% A segment is a pair of positions.  Numbering items from 0,
-	% segment P-Q stands for items P up to, but not including, Q.
-	% (Rationale: see the interpretation of type pos above.)
-	%
-	% Invariant: In any segment X - Y, it should always be true
-	% that X =< Y.  If X=Y, the segment is empty.
+    % A segment is a pair of positions.  Numbering items from 0,
+    % segment P-Q stands for items P up to, but not including, Q.
+    % (Rationale: see the interpretation of type pos above.)
+    %
+    % Invariant: In any segment X - Y, it should always be true
+    % that X =< Y.  If X=Y, the segment is empty.
 :- type segment == pair(pos,pos).

-	% An edit operation is an addition, a deletion or a change.
+    % An edit operation is an addition, a deletion or a change.
 :- type edit --->
-		add(pos,segment)
-	;	delete(segment,pos)
-	;	change(segment,segment).
-
-	% The complete diff of two file is a list of edit
-	% operations.
-	%
-	% Invariant: The edits must be in order, and must
-	% not overlap or touch.
+        add(pos,segment)
+    ;   delete(segment,pos)
+    ;   change(segment,segment).
+
+    % The complete diff of two file is a list of edit
+    % operations.
+    %
+    % Invariant: The edits must be in order, and must
+    % not overlap or touch.
 :- type diff == list(edit).

 %-----------------------------------------------------------------------------%
@@ -53,11 +55,10 @@

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

-	% Add an edit to the start of a diff, producing a new diff.
-	% This predicate determines what kind of edit this is, and
-	% merges with the adjacent edits if appropriate.
-:- pred difftype__add_edit(segment, segment, diff, diff).
-:- mode difftype__add_edit(in, in, in, out) is det.
+    % Add an edit to the start of a diff, producing a new diff.
+    % This predicate determines what kind of edit this is, and
+    % merges with the adjacent edits if appropriate.
+:- pred difftype.add_edit(segment::in, segment::in, diff::in,
diff::out) is det.

 %-----------------------------------------------------------------------------%
 %-----------------------------------------------------------------------------%
@@ -75,51 +76,51 @@

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

-difftype__add_edit(X1 - X2, Y1 - Y2, [], Diff) :-
-	( X1 = X2 ->
-		( Y1 = Y2 ->
-			Diff = []
-		;
-			Diff = [add(X1, Y1 - Y2)]
-		)
-	;
-		( Y1 = Y2 ->
-			Diff = [delete(X1 - X2, Y1)]
-		;
-			Diff = [change(X1 - X2, Y1 - Y2)]
-		)
-	).
-difftype__add_edit(X1 - X2, Y1 - Y2, [Edit0 | Diff0], Diff) :-
-	( Edit0 = add(X2, Y2 - Y3) ->
-		( X1 = X2 ->
-			Diff = [add(X1, Y1 - Y3) | Diff0]
-		;
-			Diff = [change(X1 - X2, Y1 - Y3) | Diff0]
-		)
-	; Edit0 = delete(X2 - X3, Y2) ->
-		( Y1 = Y2 ->
-			Diff = [delete(X1 - X3, Y1) | Diff0]
-		;
-			Diff = [change(X1 - X3, Y1 - Y2) | Diff0]
-		)
-	; Edit0 = change(X2 - X3, Y2 - Y3) ->
-		Diff = [change(X1 - X3, Y1 - Y3) | Diff0]
-	;
-		% This is just copied from the base case.  Pretty much.
-		( X1 = X2 ->
-			( Y1 = Y2 ->
-				Diff = [Edit0 | Diff0]
-			;
-				Diff = [add(X1, Y1 - Y2), Edit0 | Diff0]
-			)
-		;
-			( Y1 = Y2 ->
-				Diff = [delete(X1 - X2, Y1), Edit0 | Diff0]
-			;
-				Diff = [change(X1 - X2, Y1 - Y2), Edit0 | Diff0]
-			)
-		)
-	).
+difftype.add_edit(X1 - X2, Y1 - Y2, [], Diff) :-
+    ( X1 = X2 ->
+        ( Y1 = Y2 ->
+            Diff = []
+        ;
+            Diff = [add(X1, Y1 - Y2)]
+        )
+    ;
+        ( Y1 = Y2 ->
+            Diff = [delete(X1 - X2, Y1)]
+        ;
+            Diff = [change(X1 - X2, Y1 - Y2)]
+        )
+    ).
+difftype.add_edit(X1 - X2, Y1 - Y2, [Edit0 | Diff0], Diff) :-
+    ( Edit0 = add(X2, Y2 - Y3) ->
+        ( X1 = X2 ->
+            Diff = [add(X1, Y1 - Y3) | Diff0]
+        ;
+            Diff = [change(X1 - X2, Y1 - Y3) | Diff0]
+        )
+    ; Edit0 = delete(X2 - X3, Y2) ->
+        ( Y1 = Y2 ->
+            Diff = [delete(X1 - X3, Y1) | Diff0]
+        ;
+            Diff = [change(X1 - X3, Y1 - Y2) | Diff0]
+        )
+    ; Edit0 = change(X2 - X3, Y2 - Y3) ->
+        Diff = [change(X1 - X3, Y1 - Y3) | Diff0]
+    ;
+        % This is just copied from the base case.  Pretty much.
+        ( X1 = X2 ->
+            ( Y1 = Y2 ->
+                Diff = [Edit0 | Diff0]
+            ;
+                Diff = [add(X1, Y1 - Y2), Edit0 | Diff0]
+            )
+        ;
+            ( Y1 = Y2 ->
+                Diff = [delete(X1 - X2, Y1), Edit0 | Diff0]
+            ;
+                Diff = [change(X1 - X2, Y1 - Y2), Edit0 | Diff0]
+            )
+        )
+    ).

 %-----------------------------------------------------------------------------%
 %-----------------------------------------------------------------------------%
Index: samples/diff/file.m
===================================================================
RCS file: /home/mercury1/repository/mercury/samples/diff/file.m,v
retrieving revision 1.11
diff -u -r1.11 file.m
--- samples/diff/file.m	15 Sep 1998 04:54:26 -0000	1.11
+++ samples/diff/file.m	24 Apr 2006 05:48:16 -0000
@@ -1,4 +1,6 @@
 %-----------------------------------------------------------------------------%
+% vim: ft=mercury ts=4 sw=4 et
+%-----------------------------------------------------------------------------%
 % Copyright (C) 1995-1998 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.
@@ -22,42 +24,36 @@

 :- type file.

-	% file__read_file reads a file from a filename.
-:- pred file__read_file(string, io__res(file), io__state, io__state).
-:- mode file__read_file(in, out, di, uo) is det.
-
-	% file__read_input reads a file from the input
-	% stream.
-:- pred file__read_input(string, io__res(file), io__state, io__state).
-:- mode file__read_input(in, out, di, uo) is det.
-
-	% file__get_line retrieves a line from a file.
-	% (Lines are numbered from 0.)
-	% Fails if the line is out of bounds.
-:- pred file__get_line(file, int, string).
-:- mode file__get_line(in, in, out) is semidet.
-
-	% file__get_numlines returns the number of lines
-	% in a file.
-:- pred file__get_numlines(file, int).
-:- mode file__get_numlines(in, out) is det.
-
-	% file__from_list converts a list of lines to a file.
-:- pred file__from_list(string, list(string), file).
-:- mode file__from_list(in, in, out) is det.
-
-	% file__to_list converts a file into a list of
-	% lines.
-:- pred file__to_list(file, list(string)).
-:- mode file__to_list(in, out) is det.
-
-	% file__get_file_name returns the name of the file.
-:- pred file__get_file_name(file, string).
-:- mode file__get_file_name(in, out) is det.
-
-	% file__set_file_name sets the name of the file.
-:- pred file__set_file_name(file, string, file).
-:- mode file__set_file_name(in, in, out) is det.
+    % file.read_file reads a file from a filename.
+:- pred file.read_file(string::in, io.res(file)::out, io.state::di,
+        io.state::uo) is det.
+
+    % file.read_input reads a file from the input
+    % stream.
+:- pred file.read_input(string::in, io.res(file)::out, io.state::di,
+        io.state::uo) is det.
+
+    % file.get_line retrieves a line from a file.
+    % (Lines are numbered from 0.)
+    % Fails if the line is out of bounds.
+:- pred file.get_line(file::in, int::in, string::out) is semidet.
+
+    % file.get_numlines returns the number of lines
+    % in a file.
+:- pred file.get_numlines(file::in, int::out) is det.
+
+    % file.from_list converts a list of lines to a file.
+:- pred file.from_list(string::in, list(string)::in, file::out) is det.
+
+    % file.to_list converts a file into a list of
+    % lines.
+:- pred file.to_list(file::in, list(string)::out) is det.
+
+    % file.get_file_name returns the name of the file.
+:- pred file.get_file_name(file::in, string::out) is det.
+
+    % file.set_file_name sets the name of the file.
+:- pred file.set_file_name(file::in, string::in, file::out) is det.

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

@@ -67,75 +63,73 @@
 %-----------------------------------------------------------------------------%

 :- type file
-	--->	file(
-			string,			% File name
-			array(string)		% Contents
-		).
-
-	% Open the stream, read from the stream, then close
-	% the stream.
-file__read_file(FileName, File) -->
-	io__open_input(FileName, Res),
-	( { Res = ok(InputStream) },
-		file__read_stream(InputStream, Contents),
-		io__close_input(InputStream),
-		{ File = ok(file(FileName, Contents)) }
-	; { Res = error(Error) },
-		{ File = error(Error) }
-	).
-
-	% Get the input stream, then read from it.
-file__read_input(FileName, ok(file(FileName, Contents))) -->
-	io__input_stream(InputStream),
-	file__read_stream(InputStream, Contents).
-
-	% file__read_stream is the "real" file reader.
-:- pred file__read_stream(io__input_stream, array(string),
-		io__state, io__state).
-:- mode file__read_stream(in, array_uo, di, uo) is det.
-file__read_stream(Stream, File) -->
-	file__read_stream2(Stream, 0, File).
-
-	% Given a Stream from which LinesIn lines have already been
-	% read, fill File[LinesIn] to File[LinesOut-1] with the rest
-	% of the lines.  LinesOut is the number of lines in the file.
-	% (Note that line numbering starts at zero.)
-:- pred file__read_stream2(io__input_stream, int, array(string),
-		io__state, io__state).
-:- mode file__read_stream2(in, in, array_uo, di, uo) is det.
-file__read_stream2(Stream, LineNo, File) -->
-	io__read_line_as_string(Stream, Res),
-	( { Res = eof },
-		{ array__init(LineNo, "", File) }
-	; { Res = ok(Line) },
-		file__read_stream2(Stream, LineNo + 1, File1),
-		{ array__set(File1, LineNo, Line, File) }
-	; { Res = error(Error) },
-		{ io__error_message(Error, Msg) },
-		{ error(Msg) }
-	).
-
-%-----------------------------------------------------------------------------%
-
-file__get_line(file(_, Contents), LineNo, Line) :-
-	array__semidet_lookup(Contents, LineNo, Line).
-
-file__get_numlines(file(_, Contents), NumLines1 + 1) :-
-	array__bounds(Contents, _, NumLines1).
-
-%-----------------------------------------------------------------------------%
-
-file__to_list(file(_, Contents), List) :-
-	array__to_list(Contents, List).
+    --->    file(
+            string,         % File name
+            array(string)       % Contents
+        ).
+
+    % Open the stream, read from the stream, then close
+    % the stream.
+file.read_file(FileName, File, !IO) :-
+    io.open_input(FileName, Res, !IO),
+    ( Res = ok(InputStream),
+        file.read_stream(InputStream, Contents, !IO),
+        io.close_input(InputStream, !IO),
+        File = ok(file(FileName, Contents))
+    ; Res = error(Error),
+        File = error(Error)
+    ).
+
+    % Get the input stream, then read from it.
+file.read_input(FileName, ok(file(FileName, Contents)), !IO) :-
+    io.input_stream(InputStream, !IO),
+    file.read_stream(InputStream, Contents, !IO).
+
+    % file.read_stream is the "real" file reader.
+:- pred file.read_stream(io.input_stream::in, array(string)::array_uo,
+        io.state::di, io.state::uo) is det.
+file.read_stream(Stream, File, !IO) :-
+    file.read_stream2(Stream, 0, File, !IO).
+
+    % Given a Stream from which LinesIn lines have already been
+    % read, fill File[LinesIn] to File[LinesOut-1] with the rest
+    % of the lines.  LinesOut is the number of lines in the file.
+    % (Note that line numbering starts at zero.)
+:- pred file.read_stream2(io.input_stream::in, int::in,
+        array(string)::array_uo, io.state::di, io.state::uo) is det.
+file.read_stream2(Stream, LineNo, File, !IO) :-
+    io.read_line_as_string(Stream, Res, !IO),
+    ( Res = eof,
+        array.init(LineNo, "", File)
+    ; Res = ok(Line),
+        file.read_stream2(Stream, LineNo + 1, File1, !IO),
+        array.set(File1, LineNo, Line, File)
+    ; Res = error(Error),
+        io.error_message(Error, Msg),
+        error(Msg)
+    ).
+
+%-----------------------------------------------------------------------------%
+
+file.get_line(file(_, Contents), LineNo, Line) :-
+    array.semidet_lookup(Contents, LineNo, Line).
+
+file.get_numlines(file(_, Contents), NumLines1 + 1) :-
+    array.bounds(Contents, _, NumLines1).
+
+%-----------------------------------------------------------------------------%
+
+file.to_list(file(_, Contents), List) :-
+    array.to_list(Contents, List).

-file__from_list(FileName, List, file(FileName, Contents)) :-
-	array__from_list(List, Contents).
+file.from_list(FileName, List, file(FileName, Contents)) :-
+    array.from_list(List, Contents).

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

-file__get_file_name(file(FileName, _), FileName).
+file.get_file_name(file(FileName, _), FileName).

-file__set_file_name(file(_, B), FileName, file(FileName, B)).
+file.set_file_name(file(_, B), FileName, file(FileName, B)).

 %-----------------------------------------------------------------------------%
 %-----------------------------------------------------------------------------%
Index: samples/diff/filter.m
===================================================================
RCS file: /home/mercury1/repository/mercury/samples/diff/filter.m,v
retrieving revision 1.2
diff -u -r1.2 filter.m
--- samples/diff/filter.m	15 Sep 1998 04:54:28 -0000	1.2
+++ samples/diff/filter.m	24 Apr 2006 05:48:16 -0000
@@ -1,4 +1,6 @@
 %-----------------------------------------------------------------------------%
+% vim: ft=mercury ts=4 sw=4 et
+%-----------------------------------------------------------------------------%
 % Copyright (C) 1998 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.
@@ -27,7 +29,7 @@
 :- import_module difftype, file, io.

 :- pred filter_diff(diff :: in, file :: in, file :: in, diff :: out,
-		io__state :: di, io__state :: uo) is det.
+        io.state :: di, io.state :: uo) is det.

 %-----------------------------------------------------------------------------%
 %-----------------------------------------------------------------------------%
@@ -36,66 +38,65 @@
 :- import_module globals, options.
 :- import_module bool, list, int, std_util, string, char.

-filter_diff(Diff0, File1, File2, Diff) -->
-	globals__io_lookup_bool_option(ignore_blank_lines, FilterBlank),
+filter_diff(Diff0, File1, File2, Diff, !IO) :-
+    globals.io_lookup_bool_option(ignore_blank_lines, FilterBlank, !IO),

-	{ FilterBlank = no ->
-		% If we didn't request a filter, skip this pass.
+    ( FilterBlank = no ->
+        % If we didn't request a filter, skip this pass.

-		Diff = Diff0
-	;
-		filter__blank_lines(Diff0, File1, File2, Diff)
-	}.
-
-:- pred filter__blank_lines(diff :: in, file :: in, file :: in, diff :: out)
-		is det.
-
-filter__blank_lines([], _, _, []).
-filter__blank_lines([Edit | Diff0], File1, File2, Diff) :-
-	filter__blank_lines(Diff0, File1, File2, Diff1),
-	( Edit = add(_, Y1 - Y2),
-		( range_has_only_blank_lines(Y1, Y2, File2) ->
-			Diff = Diff1
-		;
-			Diff = [Edit | Diff1]
-		)
-	; Edit = delete(X1 - X2, _),
-		( range_has_only_blank_lines(X1, X2, File1) ->
-			Diff = Diff1
-		;
-			Diff = [Edit | Diff1]
-		)
-	; Edit = change(X1 - X2, Y1 - Y2),
-		(
-			range_has_only_blank_lines(X1, X2, File1),
-			range_has_only_blank_lines(Y1, Y2, File2)
-		->
-			Diff = Diff1
-		;
-			Diff = [Edit | Diff1]
-		)
-	).
+        Diff = Diff0
+    ;
+        filter.blank_lines(Diff0, File1, File2, Diff)
+    ).
+
+:- pred filter.blank_lines(diff :: in, file :: in, file :: in, diff :: out)
+        is det.
+
+filter.blank_lines([], _, _, []).
+filter.blank_lines([Edit | Diff0], File1, File2, Diff) :-
+    filter.blank_lines(Diff0, File1, File2, Diff1),
+    ( Edit = add(_, Y1 - Y2),
+        ( range_has_only_blank_lines(Y1, Y2, File2) ->
+            Diff = Diff1
+        ;
+            Diff = [Edit | Diff1]
+        )
+    ; Edit = delete(X1 - X2, _),
+        ( range_has_only_blank_lines(X1, X2, File1) ->
+            Diff = Diff1
+        ;
+            Diff = [Edit | Diff1]
+        )
+    ; Edit = change(X1 - X2, Y1 - Y2),
+        (
+            range_has_only_blank_lines(X1, X2, File1),
+            range_has_only_blank_lines(Y1, Y2, File2)
+        ->
+            Diff = Diff1
+        ;
+            Diff = [Edit | Diff1]
+        )
+    ).

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

-:- pred range_has_only_blank_lines(int, int, file).
-:- mode range_has_only_blank_lines(in, in, in) is semidet.
+:- pred range_has_only_blank_lines(int::in, int::in, file::in) is semidet.

 range_has_only_blank_lines(First, Last, File) :-
-	(
-		First < Last
-	=>
-		(
-			file__get_line(File, First, Line),
-			string__to_char_list(Line, Chars),
-			all [C] (
-				list__member(C, Chars)
-			=>
-				char__is_whitespace(C)
-			),
-			range_has_only_blank_lines(First + 1, Last, File)
-		)
-	).
+    (
+        First < Last
+    =>
+        (
+            file.get_line(File, First, Line),
+            string.to_char_list(Line, Chars),
+            all [C] (
+                list.member(C, Chars)
+            =>
+                char.is_whitespace(C)
+            ),
+            range_has_only_blank_lines(First + 1, Last, File)
+        )
+    ).

 %-----------------------------------------------------------------------------%
 %-----------------------------------------------------------------------------%
Index: samples/diff/globals.m
===================================================================
RCS file: /home/mercury1/repository/mercury/samples/diff/globals.m,v
retrieving revision 1.3
diff -u -r1.3 globals.m
--- samples/diff/globals.m	8 Feb 2001 11:37:53 -0000	1.3
+++ samples/diff/globals.m	24 Apr 2006 05:48:16 -0000
@@ -1,4 +1,6 @@
 %-----------------------------------------------------------------------------%
+% vim: ft=mercury ts=4 sw=4 et
+%-----------------------------------------------------------------------------%
 % Copyright (C) 1994-1998, 2001 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.
@@ -11,7 +13,7 @@
 % This module exports the `globals' type and associated access predicates.
 % The globals type is used to collect together all the various data
 % that would be global variables in an imperative language.
-% This global data is stored in the io__state.
+% This global data is stored in the io.state.

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

@@ -24,69 +26,68 @@

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

-	% Access predicates for the `globals' structure.
+    % Access predicates for the `globals' structure.

-:- pred globals__init(option_table::in, globals::out) is det.
+:- pred globals.init(option_table::in, globals::out) is det.

-:- pred globals__get_options(globals::in, option_table::out) is det.
+:- pred globals.get_options(globals::in, option_table::out) is det.

-:- pred globals__set_options(globals::in, option_table::in, globals::out)
-		is det.
+:- pred globals.set_options(globals::in, option_table::in, globals::out)
+        is det.

-:- pred globals__get_output_style(globals::in, diff_out__output_style::out)
-		is det.
+:- pred globals.get_output_style(globals::in, diff_out.output_style::out)
+        is det.

-:- pred globals__set_output_style(globals::in, diff_out__output_style::in,
-		globals::out) is det.
+:- pred globals.set_output_style(globals::in, diff_out.output_style::in,
+        globals::out) is det.

-:- pred globals__lookup_option(globals::in, option::in, option_data::out)
-		is det.
+:- pred globals.lookup_option(globals::in, option::in, option_data::out)
+        is det.

-:- pred globals__lookup_bool_option(globals, option, bool).
-:- mode globals__lookup_bool_option(in, in, out) is det.
-:- pred globals__lookup_int_option(globals::in, option::in, int::out) is det.
-:- pred globals__lookup_string_option(globals::in, option::in, string::out)
-		is det.
-:- pred globals__lookup_accumulating_option(globals::in, option::in,
-		list(string)::out) is det.
+:- pred globals.lookup_bool_option(globals::in, option::in, bool::out) is det.
+:- pred globals.lookup_int_option(globals::in, option::in, int::out) is det.
+:- pred globals.lookup_string_option(globals::in, option::in, string::out)
+        is det.
+:- pred globals.lookup_accumulating_option(globals::in, option::in,
+        list(string)::out) is det.

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

-	% Access predicates for storing a `globals' structure in the
-	% io__state using io__set_globals and io__get_globals.
+    % Access predicates for storing a `globals' structure in the
+    % io.state using io.set_globals and io.get_globals.

-:- pred globals__io_init(option_table::in,
-			io__state::di, io__state::uo) is det.
+:- pred globals.io_init(option_table::in,
+            io.state::di, io.state::uo) is det.

-:- pred globals__io_get_globals(globals::out, io__state::di, io__state::uo)
-			is det.
+:- pred globals.io_get_globals(globals::out, io.state::di, io.state::uo)
+            is det.

-:- pred globals__io_set_globals(globals::in, io__state::di, io__state::uo)
-			is det.
+:- pred globals.io_set_globals(globals::in, io.state::di, io.state::uo)
+            is det.

-:- pred globals__io_get_output_style(diff_out__output_style::out,
-			io__state::di, io__state::uo) is det.
+:- pred globals.io_get_output_style(diff_out.output_style::out,
+            io.state::di, io.state::uo) is det.

-:- pred globals__io_set_output_style(diff_out__output_style::in,
-			io__state::di, io__state::uo) is det.
+:- pred globals.io_set_output_style(diff_out.output_style::in,
+            io.state::di, io.state::uo) is det.

-:- pred globals__io_lookup_option(option::in, option_data::out,
-			io__state::di, io__state::uo) is det.
+:- pred globals.io_lookup_option(option::in, option_data::out,
+            io.state::di, io.state::uo) is det.

-:- pred globals__io_set_option(option::in, option_data::in,
-			io__state::di, io__state::uo) is det.
+:- pred globals.io_set_option(option::in, option_data::in,
+            io.state::di, io.state::uo) is det.

-:- pred globals__io_lookup_bool_option(option, bool, io__state, io__state).
-:- mode globals__io_lookup_bool_option(in, out, di, uo) is det.
+:- pred globals.io_lookup_bool_option(option::in, bool::out,
+        io.state::di, io.state::uo) is det.

-:- pred globals__io_lookup_int_option(option::in, int::out,
-			io__state::di, io__state::uo) is det.
+:- pred globals.io_lookup_int_option(option::in, int::out,
+            io.state::di, io.state::uo) is det.

-:- pred globals__io_lookup_string_option(option::in, string::out,
-			io__state::di, io__state::uo) is det.
+:- pred globals.io_lookup_string_option(option::in, string::out,
+            io.state::di, io.state::uo) is det.

-:- pred globals__io_lookup_accumulating_option(option::in, list(string)::out,
-			io__state::di, io__state::uo) is det.
+:- pred globals.io_lookup_accumulating_option(option::in, list(string)::out,
+            io.state::di, io.state::uo) is det.

 %-----------------------------------------------------------------------------%
 %-----------------------------------------------------------------------------%
@@ -97,124 +98,124 @@
 %-----------------------------------------------------------------------------%

 :- type globals
-	--->	globals(
-			option_table,		% Current options
-			diff_out__output_style	% Current module name
-		).
+    --->    globals(
+            option_table,       % Current options
+            diff_out.output_style   % Current module name
+        ).

-globals__init(Options, globals(Options, OutputType)) :-
-	diff_out__default_output_style(OutputType).
+globals.init(Options, globals(Options, OutputType)) :-
+    diff_out.default_output_style(OutputType).

-globals__get_options(globals(Options, _), Options).
+globals.get_options(globals(Options, _), Options).

-globals__set_options(globals(_, Scanner), Options, globals(Options, Scanner)).
+globals.set_options(globals(_, Scanner), Options, globals(Options, Scanner)).

-globals__get_output_style(globals(_, Output), Output).
+globals.get_output_style(globals(_, Output), Output).

-globals__set_output_style(globals(A, _), Output, globals(A, Output)).
+globals.set_output_style(globals(A, _), Output, globals(A, Output)).

-globals__lookup_option(Globals, Option, OptionData) :-
-	globals__get_options(Globals, OptionTable),
-	map__lookup(OptionTable, Option, OptionData).
+globals.lookup_option(Globals, Option, OptionData) :-
+    globals.get_options(Globals, OptionTable),
+    map.lookup(OptionTable, Option, OptionData).

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

-globals__lookup_bool_option(Globals, Option, Value) :-
-	globals__lookup_option(Globals, Option, OptionData),
-	( OptionData = bool(Bool) ->
-		Value = Bool
-	;
-		error("globals__lookup_bool_option: invalid bool option")
-	).
+globals.lookup_bool_option(Globals, Option, Value) :-
+    globals.lookup_option(Globals, Option, OptionData),
+    ( OptionData = bool(Bool) ->
+        Value = Bool
+    ;
+        error("globals.lookup_bool_option: invalid bool option")
+    ).

-globals__lookup_string_option(Globals, Option, Value) :-
-	globals__lookup_option(Globals, Option, OptionData),
-	( OptionData = string(String) ->
-		Value = String
-	;
-		error("globals__lookup_string_option: invalid string option")
-	).
+globals.lookup_string_option(Globals, Option, Value) :-
+    globals.lookup_option(Globals, Option, OptionData),
+    ( OptionData = string(String) ->
+        Value = String
+    ;
+        error("globals.lookup_string_option: invalid string option")
+    ).

-globals__lookup_int_option(Globals, Option, Value) :-
-	globals__lookup_option(Globals, Option, OptionData),
-	( OptionData = int(Int) ->
-		Value = Int
-	;
-		error("globals__lookup_int_option: invalid int option")
-	).
+globals.lookup_int_option(Globals, Option, Value) :-
+    globals.lookup_option(Globals, Option, OptionData),
+    ( OptionData = int(Int) ->
+        Value = Int
+    ;
+        error("globals.lookup_int_option: invalid int option")
+    ).

-globals__lookup_accumulating_option(Globals, Option, Value) :-
-	globals__lookup_option(Globals, Option, OptionData),
-	( OptionData = accumulating(Accumulating) ->
-		Value = Accumulating
-	;
-		error("globals__lookup_accumulating_option: invalid accumulating option")
-	).
+globals.lookup_accumulating_option(Globals, Option, Value) :-
+    globals.lookup_option(Globals, Option, OptionData),
+    ( OptionData = accumulating(Accumulating) ->
+        Value = Accumulating
+    ;
+        error("globals.lookup_accumulating_option: invalid
accumulating option")
+    ).

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

-globals__io_init(Options) -->
-	{ globals__init(Options, Globals) },
-	globals__io_set_globals(Globals).
+globals.io_init(Options, !IO) :-
+    globals.init(Options, Globals),
+    globals.io_set_globals(Globals, !IO).

-globals__io_get_globals(Globals) -->
-	io__get_globals(UnivGlobals),
-	{
-		univ_to_type(UnivGlobals, Globals0)
-	->
-		Globals = Globals0
-	;
-		error("globals__io_get_globals: univ_to_type failed")
-	}.
+globals.io_get_globals(Globals, !IO) :-
+    io.get_globals(UnivGlobals, !IO),
+    (
+        univ_to_type(UnivGlobals, Globals0)
+    ->
+        Globals = Globals0
+    ;
+        error("globals.io_get_globals: univ_to_type failed")
+    ).

-globals__io_set_globals(Globals) -->
-	{ unsafe_promise_unique(Globals, UniqGlobals) },
-	{ type_to_univ(UniqGlobals, UnivGlobals) },
-	io__set_globals(UnivGlobals).
+globals.io_set_globals(Globals, !IO) :-
+    unsafe_promise_unique(Globals, UniqGlobals),
+    type_to_univ(UniqGlobals, UnivGlobals),
+    io.set_globals(UnivGlobals, !IO).

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

-globals__io_lookup_option(Option, OptionData) -->
-	globals__io_get_globals(Globals),
-	{ globals__get_options(Globals, OptionTable) },
-	{ map__lookup(OptionTable, Option, OptionData) }.
+globals.io_lookup_option(Option, OptionData, !IO) :-
+    globals.io_get_globals(Globals, !IO),
+    globals.get_options(Globals, OptionTable),
+    map.lookup(OptionTable, Option, OptionData).

-globals__io_set_option(Option, OptionData) -->
-	globals__io_get_globals(Globals0),
-	{ globals__get_options(Globals0, OptionTable0) },
-	{ map__set(OptionTable0, Option, OptionData, OptionTable) },
-	{ globals__set_options(Globals0, OptionTable, Globals) },
-	globals__io_set_globals(Globals).
+globals.io_set_option(Option, OptionData, !IO) :-
+    globals.io_get_globals(Globals0, !IO),
+    globals.get_options(Globals0, OptionTable0),
+    map.set(OptionTable0, Option, OptionData, OptionTable),
+    globals.set_options(Globals0, OptionTable, Globals),
+    globals.io_set_globals(Globals, !IO).

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

-globals__io_lookup_bool_option(Option, Value) -->
-	globals__io_get_globals(Globals),
-	{ globals__lookup_bool_option(Globals, Option, Value) }.
+globals.io_lookup_bool_option(Option, Value, !IO) :-
+    globals.io_get_globals(Globals, !IO),
+    globals.lookup_bool_option(Globals, Option, Value).

-globals__io_lookup_int_option(Option, Value) -->
-	globals__io_get_globals(Globals),
-	{ globals__lookup_int_option(Globals, Option, Value) }.
+globals.io_lookup_int_option(Option, Value, !IO) :-
+    globals.io_get_globals(Globals, !IO),
+    globals.lookup_int_option(Globals, Option, Value).

-globals__io_lookup_string_option(Option, Value) -->
-	globals__io_get_globals(Globals),
-	{ globals__lookup_string_option(Globals, Option, Value) }.
+globals.io_lookup_string_option(Option, Value, !IO) :-
+    globals.io_get_globals(Globals, !IO),
+    globals.lookup_string_option(Globals, Option, Value).

-globals__io_lookup_accumulating_option(Option, Value) -->
-	globals__io_get_globals(Globals),
-	{ globals__lookup_accumulating_option(Globals, Option, Value) }.
+globals.io_lookup_accumulating_option(Option, Value, !IO) :-
+    globals.io_get_globals(Globals, !IO),
+    globals.lookup_accumulating_option(Globals, Option, Value).

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

-globals__io_get_output_style(Output) -->
-	globals__io_get_globals(Globals),
-	{ globals__get_output_style(Globals, Output) }.
+globals.io_get_output_style(Output, !IO) :-
+    globals.io_get_globals(Globals, !IO),
+    globals.get_output_style(Globals, Output).

-globals__io_set_output_style(Output) -->
-	globals__io_get_globals(Globals0),
-	{ globals__set_output_style(Globals0, Output, Globals) },
-	globals__io_set_globals(Globals).
+globals.io_set_output_style(Output, !IO) :-
+    globals.io_get_globals(Globals0, !IO),
+    globals.set_output_style(Globals0, Output, Globals),
+    globals.io_set_globals(Globals, !IO).

 %-----------------------------------------------------------------------------%
 %-----------------------------------------------------------------------------%
Index: samples/diff/match.m
===================================================================
RCS file: /home/mercury1/repository/mercury/samples/diff/match.m,v
retrieving revision 1.1
diff -u -r1.1 match.m
--- samples/diff/match.m	15 Sep 1998 04:54:33 -0000	1.1
+++ samples/diff/match.m	24 Apr 2006 05:48:16 -0000
@@ -1,4 +1,6 @@
 %-----------------------------------------------------------------------------%
+% vim: ft=mercury ts=4 sw=4 et
+%-----------------------------------------------------------------------------%
 % Copyright (C) 1998 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.
@@ -20,9 +22,9 @@
 %        file and pretend the whole sequence is just one line.  (GNU
 %        diff does the same thing a slightly different way, but this
 %        approach seems a bit more Mercury-esque.)  Since Myers'
-%	 algorithm runs in O(ND) time, and performing this pre-filtering
-%	 here would reduce the value of D (by quite a lot in real-world
-%	 cases), things should speed up.
+%    algorithm runs in O(ND) time, and performing this pre-filtering
+%    here would reduce the value of D (by quite a lot in real-world
+%    cases), things should speed up.

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

@@ -32,8 +34,8 @@
 :- import_module file, io, array.

 :- pred build_matches(file :: in, file :: in,
-		array(int) :: out, array(int) :: out,
-		io__state :: di, io__state :: uo) is det.
+        array(int) :: out, array(int) :: out,
+        io.state :: di, io.state :: uo) is det.

 %-----------------------------------------------------------------------------%
 %-----------------------------------------------------------------------------%
@@ -43,110 +45,109 @@
 :- import_module bool, list, int, std_util, string, char, map, require.

 :- type match_options
-	--->	match_options(
-			bool,		% No options set
-			bool,		% --ignore-case
-			bool,		% --ignore-all-space
-			bool		% --ignore-space-change
-		).
-
-build_matches(File1, File2, FileX, FileY) -->
-	globals__io_lookup_bool_option(ignore_case, IgnCase),
-	globals__io_lookup_bool_option(ignore_all_space, IgnAllSpc),
-	globals__io_lookup_bool_option(ignore_space_change, IgnSpcChg),
-	{
-		bool__or_list([IgnCase, IgnAllSpc, IgnSpcChg], AnyOpts),
-		bool__not(AnyOpts, NoOpts),
-		Opts = match_options(NoOpts, IgnCase, IgnAllSpc, IgnSpcChg),
-		map__init(MatchMap0),
-		file__get_numlines(File1, SizeX),
-		array__init(SizeX, -1, FileX0),
-		build_matches_for_file(Opts, File1, SizeX - 1, MatchMap0,
-			MatchMap1, 0, ID1, FileX0, FileX),
-		file__get_numlines(File2, SizeY),
-		array__init(SizeY, -1, FileY0),
-		build_matches_for_file(Opts, File2, SizeY - 1, MatchMap1, _,
-			ID1, _, FileY0, FileY)
-	}.
-
-:- pred build_matches_for_file(match_options, file, int,
-	map(string, int), map(string, int), int, int, array(int), array(int)).
-:- mode build_matches_for_file(in, in, in, in, out, in, out,
-	array_di, array_uo) is det.
+    --->    match_options(
+            bool,       % No options set
+            bool,       % --ignore-case
+            bool,       % --ignore-all-space
+            bool        % --ignore-space-change
+        ).
+
+build_matches(File1, File2, FileX, FileY, !IO) :-
+    globals.io_lookup_bool_option(ignore_case, IgnCase, !IO),
+    globals.io_lookup_bool_option(ignore_all_space, IgnAllSpc, !IO),
+    globals.io_lookup_bool_option(ignore_space_change, IgnSpcChg, !IO),
+    (
+        bool.or_list([IgnCase, IgnAllSpc, IgnSpcChg], AnyOpts),
+        bool.not(AnyOpts, NoOpts),
+        Opts = match_options(NoOpts, IgnCase, IgnAllSpc, IgnSpcChg),
+        map.init(MatchMap0),
+        file.get_numlines(File1, SizeX),
+        array.init(SizeX, -1, FileX0),
+        build_matches_for_file(Opts, File1, SizeX - 1, MatchMap0,
+            MatchMap1, 0, ID1, FileX0, FileX),
+        file.get_numlines(File2, SizeY),
+        array.init(SizeY, -1, FileY0),
+        build_matches_for_file(Opts, File2, SizeY - 1, MatchMap1, _,
+            ID1, _, FileY0, FileY)
+    ).
+
+:- pred build_matches_for_file(match_options::in, file::in, int::in,
+    map(string, int)::in, map(string, int)::out, int::in, int::out,
+    array(int)::array_di, array(int)::array_uo) is det.

 build_matches_for_file(Opts, OrigFile, I, MatchMap0, MatchMap, ID0, ID,
-		File0, File) :-
-	( I < 0 ->
-		MatchMap = MatchMap0,
-		ID = ID0,
-		File = File0
-	;
-		( file__get_line(OrigFile, I, Line0) ->
-			Line1 = Line0
-		;
-			error("build_matches_for_file")
-		),
-		Opts = match_options(NoOpts, IgnCase, IgnAllSpc, IgnSpcChg),
-		( NoOpts = yes ->
-			Line = Line1
-		;
-			string__to_char_list(Line1, Chars0),
-			normalise_line(no, IgnCase, IgnAllSpc, IgnSpcChg,
-				Chars0, Chars1),
-			string__from_char_list(Chars1, Line)
-		),
-		( map__search(MatchMap0, Line, MaybeID) ->
-			array__set(File0, I, MaybeID, File1),
-			MatchMap1 = MatchMap0,
-			ID1 = ID0
-		;
-			array__set(File0, I, ID0, File1),
-			map__det_insert(MatchMap0, Line, ID0, MatchMap1),
-			ID1 is ID0 + 1
-		),
-		build_matches_for_file(Opts, OrigFile, I - 1, MatchMap1,
-			MatchMap, ID1, ID, File1, File)
-	).
+        File0, File) :-
+    ( I < 0 ->
+        MatchMap = MatchMap0,
+        ID = ID0,
+        File = File0
+    ;
+        ( file.get_line(OrigFile, I, Line0) ->
+            Line1 = Line0
+        ;
+            error("build_matches_for_file")
+        ),
+        Opts = match_options(NoOpts, IgnCase, IgnAllSpc, IgnSpcChg),
+        ( NoOpts = yes ->
+            Line = Line1
+        ;
+            string.to_char_list(Line1, Chars0),
+            normalise_line(no, IgnCase, IgnAllSpc, IgnSpcChg,
+                Chars0, Chars1),
+            string.from_char_list(Chars1, Line)
+        ),
+        ( map.search(MatchMap0, Line, MaybeID) ->
+            array.set(File0, I, MaybeID, File1),
+            MatchMap1 = MatchMap0,
+            ID1 = ID0
+        ;
+            array.set(File0, I, ID0, File1),
+            map.det_insert(MatchMap0, Line, ID0, MatchMap1),
+            ID1 is ID0 + 1
+        ),
+        build_matches_for_file(Opts, OrigFile, I - 1, MatchMap1,
+            MatchMap, ID1, ID, File1, File)
+    ).

-:- pred normalise_line(bool, bool, bool, bool, list(char), list(char)).
-:- mode normalise_line(in, in, in, in, in, out) is det.
+:- pred normalise_line(bool::in, bool::in, bool::in, bool::in,
+    list(char)::in, list(char)::out) is det.

 normalise_line(_, _, _, _, [], []).
 normalise_line(LastSpace, IgnCase, IgnAllSpc, IgnSpcChg, [C0 | Cs0], Cs) :-
-	( IgnCase = yes ->
-		char__to_lower(C0, C)
-	;
-		C = C0
-	),
-	(
-		char__is_whitespace(C),
-		(
-			IgnAllSpc = yes
-		->
-			normalise_line(LastSpace, IgnCase, IgnAllSpc, IgnSpcChg,
-					Cs0, CsX)
-		;
-			IgnSpcChg = yes
-		->
-			( LastSpace = yes ->
-				normalise_line(yes, IgnCase, IgnAllSpc,
-						IgnSpcChg, Cs0, CsX)
-			;
-				normalise_line(yes, IgnCase, IgnAllSpc,
-						IgnSpcChg, Cs0, Cs1),
-				CsX = [' ' | Cs1]
-				
-			)
-		;
-			fail
-		)
-	->
-		Cs = CsX
-	;
-		normalise_line(no, IgnCase, IgnAllSpc, IgnSpcChg,
-				Cs0, Cs1),
-		Cs = [C | Cs1]
-	).
+    ( IgnCase = yes ->
+        char.to_lower(C0, C)
+    ;
+        C = C0
+    ),
+    (
+        char.is_whitespace(C),
+        (
+            IgnAllSpc = yes
+        ->
+            normalise_line(LastSpace, IgnCase, IgnAllSpc, IgnSpcChg,
+                    Cs0, CsX)
+        ;
+            IgnSpcChg = yes
+        ->
+            ( LastSpace = yes ->
+                normalise_line(yes, IgnCase, IgnAllSpc,
+                        IgnSpcChg, Cs0, CsX)
+            ;
+                normalise_line(yes, IgnCase, IgnAllSpc,
+                        IgnSpcChg, Cs0, Cs1),
+                CsX = [' ' | Cs1]
+
+            )
+        ;
+            fail
+        )
+    ->
+        Cs = CsX
+    ;
+        normalise_line(no, IgnCase, IgnAllSpc, IgnSpcChg,
+                Cs0, Cs1),
+        Cs = [C | Cs1]
+    ).

 %-----------------------------------------------------------------------------%
 %-----------------------------------------------------------------------------%
Index: samples/diff/myers.m
===================================================================
RCS file: /home/mercury1/repository/mercury/samples/diff/myers.m,v
retrieving revision 1.1
diff -u -r1.1 myers.m
--- samples/diff/myers.m	15 Sep 1998 04:54:36 -0000	1.1
+++ samples/diff/myers.m	24 Apr 2006 05:48:16 -0000
@@ -1,4 +1,6 @@
 %-----------------------------------------------------------------------------%
+% vim: ft=mercury ts=4 sw=4 et
+%-----------------------------------------------------------------------------%
 % Copyright (C) 1998 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.
@@ -7,14 +9,14 @@
 % Main author: bromage

 % TO DO: We should implement the big-snake heuristic (a.k.a.
-%	--speed-large-files).
+%   --speed-large-files).
 %
 % ALSO TO DO: Gene Myers et al have since produced another algorithm
-%	which takes O(NP) time where P is the number of deletions in
-%	the edit script.  If the `too expensive' heuristic can be
-%	retro-fitted onto that algorithm easily enough, we should try
-%	out this algorithm and see how fast it runs.  In theory, we
-%	should be looking at about a 2x speedup.
+%   which takes O(NP) time where P is the number of deletions in
+%   the edit script.  If the `too expensive' heuristic can be
+%   retro-fitted onto that algorithm easily enough, we should try
+%   out this algorithm and see how fast it runs.  In theory, we
+%   should be looking at about a 2x speedup.

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

@@ -23,8 +25,8 @@
 :- interface.
 :- import_module difftype, array, io.

-:- pred diff_by_myers(array(int), array(int), diff, io__state, io__state).
-:- mode diff_by_myers(in, in, out, di, uo) is det.
+:- pred diff_by_myers(array(int)::in, array(int)::in, diff::out,
+        io.state::di, io.state::uo) is det.

 %-----------------------------------------------------------------------------%
 %-----------------------------------------------------------------------------%
@@ -34,466 +36,454 @@
 :- import_module map, require, std_util, int, list, char, bool.

 % The basic algorithm is described in:
-%	"An O(ND) Difference Algorithm and its Variations", Eugene Myers,
-%	Algorithmica Vol. 1 No. 2, 1986, pp. 251-266.
+%   "An O(ND) Difference Algorithm and its Variations", Eugene Myers,
+%   Algorithmica Vol. 1 No. 2, 1986, pp. 251-266.
 %
 % This uses the variation in section 4b.

-diff_by_myers(FileX, FileY, Diff) -->
-	globals__io_lookup_bool_option(minimal, Minimal),
-	{
-		array__size(FileX, SizeX),
-		array__size(FileY, SizeY),
-		SizeMax = SizeX + SizeY + 3,
-		DOffset = SizeY + 1,
-
-		% If we don't insist on --minimal, calculate the
-		% approximate square root of the input size for
-		% the "too expensive" heuristic.  The effect of
-		% this is to limit the amount of work to about
-		% O(n ** (1.5 log n)) at the expense of finding a
-		% possibly non-minimal diff.
-
-		( Minimal = yes,
-			Heur = none
-		; Minimal = no,
-			int__log2(SizeMax, SizeLog2),
-			int__max(minimum_too_expensive, 1 << (SizeLog2 // 2),
-					SizeHeuristic),
-			Heur = too_expensive(SizeHeuristic)
-		),
-
-			% Fill the arrays with nondescript numbers which
-			% the algorithm shouldn't produce.  (For debugging
-			% purposes.)
-		array__init(SizeMax, -65537, Fwd),
-		array__init(SizeMax, -65537, Bwd),
-		myers__bsearch(DOffset, FileX, FileY, 0, SizeX, 0, SizeY,
-			Heur, Fwd, _, Bwd, _, [], Diff)
-	}.
+diff_by_myers(FileX, FileY, Diff, !IO) :-
+    globals.io_lookup_bool_option(minimal, Minimal, !IO),
+    (
+        array.size(FileX, SizeX),
+        array.size(FileY, SizeY),
+        SizeMax = SizeX + SizeY + 3,
+        DOffset = SizeY + 1,
+
+        % If we don't insist on --minimal, calculate the
+        % approximate square root of the input size for
+        % the "too expensive" heuristic.  The effect of
+        % this is to limit the amount of work to about
+        % O(n ** (1.5 log n)) at the expense of finding a
+        % possibly non-minimal diff.
+
+        ( Minimal = yes,
+            Heur = none
+        ; Minimal = no,
+            int.log2(SizeMax, SizeLog2),
+            int.max(minimum_too_expensive, 1 << (SizeLog2 // 2),
+                    SizeHeuristic),
+            Heur = too_expensive(SizeHeuristic)
+        ),
+
+            % Fill the arrays with nondescript numbers which
+            % the algorithm shouldn't produce.  (For debugging
+            % purposes.)
+        array.init(SizeMax, -65537, Fwd),
+        array.init(SizeMax, -65537, Bwd),
+        myers.bsearch(DOffset, FileX, FileY, 0, SizeX, 0, SizeY,
+            Heur, Fwd, _, Bwd, _, [], Diff)
+    ).

-	% XXX This lower bound is a guess.  Need to do some measurements
-	%     to see if it's good or not.
+    % XXX This lower bound is a guess.  Need to do some measurements
+    %     to see if it's good or not.
 :- func minimum_too_expensive = int.
 minimum_too_expensive = 256.

-:- pred myers__bsearch(int, array(int), array(int), int, int, int, int, heur,
-		array(int), array(int), array(int), array(int),
-		diff, diff).
-:- mode myers__bsearch(in, in, in, in, in, in, in, in,
-		array_di, array_uo, array_di, array_uo,
-		in, out) is det.
-
-myers__bsearch(DOffset, FileX, FileY, Xlow0, Xhigh0, Ylow0, Yhigh0, Heur,
-			Fwd0, Fwd, Bwd0, Bwd, Diff0, Diff) :-
-	myers__scan_forward(FileX, FileY, Xhigh0, Yhigh0,
-		Xlow0, Xlow, Ylow0, Ylow),
-	myers__scan_backward(FileX, FileY, Xlow, Ylow,
-		Xhigh0, Xhigh, Yhigh0, Yhigh),
-
-	(
-		( Xlow >= Xhigh
-		; Ylow >= Yhigh
-		)
-	->
-		Fwd = Fwd0, Bwd = Bwd0,
-		difftype__add_edit(Xlow - Xhigh, Ylow - Yhigh, Diff0, Diff)
-	;
-		myers__find_middle(DOffset, FileX, FileY,
-			Xlow, Xhigh, Ylow, Yhigh, Heur,
-			Fwd0, Fwd1, Bwd0, Bwd1, Xmid, Ymid, Cost,
-			LeftHeur - RightHeur),
-		(
-			Cost > 0
-		->
-			myers__bsearch(DOffset, FileX, FileY,
-				Xmid, Xhigh, Ymid, Yhigh, LeftHeur,
-				Fwd1, Fwd2, Bwd1, Bwd2, Diff0, Diff1),
-			myers__bsearch(DOffset, FileX, FileY,
-				Xlow, Xmid, Ylow, Ymid, RightHeur,
-				Fwd2, Fwd, Bwd2, Bwd, Diff1, Diff)
-		;
-			error("myers__bsearch")
-		)
-	).
+:- pred myers.bsearch(int::in, array(int)::in, array(int)::in, int::in,
+        int::in, int::in, int::in, heur::in,
+        array(int)::array_di, array(int)::array_uo,
+        array(int)::array_di, array(int)::array_uo,
+        diff::in, diff::out) is det.
+
+myers.bsearch(DOffset, FileX, FileY, Xlow0, Xhigh0, Ylow0, Yhigh0, Heur,
+            Fwd0, Fwd, Bwd0, Bwd, Diff0, Diff) :-
+    myers.scan_forward(FileX, FileY, Xhigh0, Yhigh0,
+        Xlow0, Xlow, Ylow0, Ylow),
+    myers.scan_backward(FileX, FileY, Xlow, Ylow,
+        Xhigh0, Xhigh, Yhigh0, Yhigh),
+
+    (
+        ( Xlow >= Xhigh
+        ; Ylow >= Yhigh
+        )
+    ->
+        Fwd = Fwd0, Bwd = Bwd0,
+        difftype.add_edit(Xlow - Xhigh, Ylow - Yhigh, Diff0, Diff)
+    ;
+        myers.find_middle(DOffset, FileX, FileY,
+            Xlow, Xhigh, Ylow, Yhigh, Heur,
+            Fwd0, Fwd1, Bwd0, Bwd1, Xmid, Ymid, Cost,
+            LeftHeur - RightHeur),
+        (
+            Cost > 0
+        ->
+            myers.bsearch(DOffset, FileX, FileY,
+                Xmid, Xhigh, Ymid, Yhigh, LeftHeur,
+                Fwd1, Fwd2, Bwd1, Bwd2, Diff0, Diff1),
+            myers.bsearch(DOffset, FileX, FileY,
+                Xlow, Xmid, Ylow, Ymid, RightHeur,
+                Fwd2, Fwd, Bwd2, Bwd, Diff1, Diff)
+        ;
+            error("myers.bsearch")
+        )
+    ).

 :- type myers_constants
-	--->	constants(
-			int,		% DOffset
-			array(int),	% X
-			array(int),	% Y
-			int,		% Xlow
-			int,		% Xhigh
-			int,		% Ylow
-			int,		% Yhigh
-			int,		% Dmin
-			int,		% Dmax
-			bool,		% DeltaOdd
-			heur		% "Too expensive" heuristic.
-		).
+    --->    constants(
+            int,        % DOffset
+            array(int), % X
+            array(int), % Y
+            int,        % Xlow
+            int,        % Xhigh
+            int,        % Ylow
+            int,        % Yhigh
+            int,        % Dmin
+            int,        % Dmax
+            bool,       % DeltaOdd
+            heur        % "Too expensive" heuristic.
+        ).

 :- type heur
-	--->	too_expensive(int)
-	;	none.
+    --->    too_expensive(int)
+    ;   none.

-	% The best part about this algorithm is: We don't actually
-	% need to find the middle of the diff.  We only have to find
-	% an estimate to it.  If we don't find the exact middle,
-	% we will have a correct diff, but it won't necessarily be
-	% minimal.
-:- pred myers__find_middle(int, array(int), array(int), pos, pos, pos, pos,
-		heur,
-		array(int), array(int), array(int), array(int),
-		pos, pos, int, pair(heur)).
-:- mode myers__find_middle(in, in, in, in, in, in, in, in,
-		array_di, array_uo, array_di, array_uo,
-		out, out, out, out) is det.
-
-myers__find_middle(DOffset, FileX, FileY, Xlow, Xhigh, Ylow, Yhigh, Heur,
-		Fwd0, Fwd, Bwd0, Bwd, Xmid, Ymid, Cost, HeurReq) :-
-
-	Dmin = Xlow - Yhigh,
-	Dmax = Xhigh - Ylow,
-
-	Fmid = Xlow - Ylow,
-	array__set(Fwd0, Fmid + DOffset, Xlow, Fwd1),
-	Bmid = Xhigh - Yhigh,
-	array__set(Bwd0, Bmid + DOffset, Xhigh, Bwd1),
-
-	( 1 = (Fmid - Bmid) /\ 1 ->
-		DeltaOdd = yes
-	;
-		DeltaOdd = no
-	),
-
-	Constants = constants(
-		DOffset, FileX, FileY, Xlow, Xhigh, Ylow, Yhigh,
-		Dmin, Dmax, DeltaOdd, Heur
-	),
-
-	myers__find_middle_2(Constants, Fwd1, Fwd, Bwd1, Bwd,
-		Fmid, Fmid, Bmid, Bmid, 1, Cost, Xmid - Ymid, HeurReq).
-
-
-:- pred myers__find_middle_2(myers_constants,
-		array(int), array(int), array(int), array(int),
-		int, int, int, int, int, int, pair(pos), pair(heur)).
-:- mode myers__find_middle_2(in, array_di, array_uo, array_di, array_uo,
-		in, in, in, in, in, out, out, out) is det.
-
-myers__find_middle_2(Constants, Fwd0, Fwd, Bwd0, Bwd,
-		Fmin, Fmax, Bmin, Bmax, Cost0, Cost, Mid, HeurReq) :-
-	Constants = constants(DOffset, _, _, _, _, _, _, Dmin, Dmax, _, _),
-	( Fmin > Dmin ->
-		Fmin1 = Fmin - 1,
-		array__set(Fwd0, Fmin1 + DOffset - 1, -1, Fwd1)
-	;
-		Fmin1 = Fmin + 1,
-		Fwd1 = Fwd0
-	),
-	( Fmax < Dmax ->
-		Fmax1 = Fmax + 1,
-		array__set(Fwd1, Fmax1 + DOffset + 1, -1, Fwd2)
-	;
-		Fmax1 = Fmax - 1,
-		Fwd2 = Fwd1
-	),
-	myers__find_forward_reaching_path(Constants, Fwd2, Fwd, Bwd0, Bwd,
-		Fmin1, Fmax1, Bmin, Bmax, Fmax1, Cost0, Cost, Mid, HeurReq).
-
-
-:- pred myers__find_forward_reaching_path(myers_constants,
-		array(int), array(int), array(int), array(int),
-		int, int, int, int, int, int, int, pair(pos), pair(heur)).
-:- mode myers__find_forward_reaching_path(in, array_di, array_uo,
-		array_di, array_uo, in, in, in, in, in, in, out, out, out)
-				is det.
-
-myers__find_forward_reaching_path(Constants, Fwd0, Fwd, Bwd0, Bwd,
-		Fmin, Fmax, Bmin, Bmax, SearchCost, Cost0, Cost, Mid,
-		HeurReq) :-
-	( SearchCost < Fmin ->
-		Constants = constants(DOffset, _, _, _, _, _, _, Dmin, Dmax, _,
-					_),
-		int__max_int(MaxInt),
-		( Bmin > Dmin ->
-			Bmin1 = Bmin - 1,
-			array__set(Bwd0, Bmin1 + DOffset - 1, MaxInt, Bwd1)
-		;
-			Bmin1 = Bmin + 1,
-			Bwd1 = Bwd0
-		),
-		( Bmax < Dmax ->
-			Bmax1 = Bmax + 1,
-			array__set(Bwd1, Bmax1 + DOffset + 1, MaxInt, Bwd2)
-		;
-			Bmax1 = Bmax - 1,
-			Bwd2 = Bwd1
-		),
-		myers__find_backward_reaching_path(Constants,
-			Fwd0, Fwd, Bwd2, Bwd, Fmin, Fmax, Bmin1, Bmax1,
-			Bmax1, Cost0, Cost, Mid, HeurReq)
-	;
-		Constants = constants(DOffset, _, _, _, _, _, _, _, _, _, _),
-		array__lookup(Fwd0, SearchCost + DOffset - 1, Tlo),
-		array__lookup(Fwd0, SearchCost + DOffset + 1, Thi),
-		( Tlo >= Thi ->
-			X0 = Tlo + 1
-		;
-			X0 = Thi
-		),
-		Y0 = X0 - SearchCost,
-		Constants = constants(_, FileX, FileY, _, Xhigh, _, Yhigh,
-			_, _, _, _),
-		myers__scan_forward(FileX, FileY, Xhigh, Yhigh, X0, X, Y0, Y),
-		array__set(Fwd0, SearchCost + DOffset, X, Fwd1),
-
-		Constants = constants(_, _, _, _, _, _, _, _, _, DeltaOdd, _),
-		(
-			DeltaOdd = yes,
-			Bmin =< SearchCost,
-			SearchCost =< Bmax,
-			array__lookup(Bwd0, SearchCost + DOffset, BB),
-			BB =< X
-		->
-			Mid = X - Y,
-			Cost = 2 * Cost0 + 1,
-			Fwd = Fwd1,
-			Bwd = Bwd0,
-			HeurReq = none - none
-		;
-			myers__find_forward_reaching_path(Constants,
-				Fwd1, Fwd, Bwd0, Bwd, Fmin, Fmax, Bmin, Bmax,
-				SearchCost - 2, Cost0, Cost, Mid, HeurReq)
-		)
-	).
-
-
-:- pred myers__find_backward_reaching_path(myers_constants,
-		array(int), array(int), array(int), array(int),
-		int, int, int, int, int, int, int, pair(pos), pair(heur)).
-:- mode myers__find_backward_reaching_path(in, array_di, array_uo,
-		array_di, array_uo, in, in, in, in, in, in,
-		out, out, out) is det.
-
-myers__find_backward_reaching_path(Constants, Fwd0, Fwd, Bwd0, Bwd,
-		Fmin, Fmax, Bmin, Bmax, SearchCost, Cost0, Cost, Mid,
-		HeurReq) :-
-	( SearchCost < Bmin ->
-		myers__try_heuristics(Constants, Fwd0, Fwd, Bwd0, Bwd,
-			Fmin, Fmax, Bmin, Bmax, Cost0, Cost, Mid, HeurReq)
-	;
-		Constants = constants(DOffset, _, _, _, _, _, _, _, _, _, _),
-		array__lookup(Bwd0, SearchCost + DOffset - 1, Tlo),
-		array__lookup(Bwd0, SearchCost + DOffset + 1, Thi),
-		( Tlo < Thi ->
-			X0 = Tlo
-		;
-			X0 = Thi - 1
-		),
-		Y0 = X0 - SearchCost,
-		Constants = constants(_, FileX, FileY, Xlow, _, Ylow, _,
-			_, _, _, _),
-		myers__scan_backward(FileX, FileY, Xlow, Ylow, X0, X, Y0, Y),
-		array__set(Bwd0, SearchCost + DOffset, X, Bwd1),
-
-		Constants = constants(_, _, _, _, _, _, _, _, _, DeltaOdd, _),
-		(
-			DeltaOdd = no,
-			Fmin =< SearchCost,
-			SearchCost =< Fmax,
-			array__lookup(Fwd0, SearchCost + DOffset, FF),
-			X =< FF
-		->
-			Mid = X - Y,
-			Cost = 2 * Cost0,
-			Fwd = Fwd0,
-			Bwd = Bwd1,
-			HeurReq = none - none
-		;
-			myers__find_backward_reaching_path(Constants,
-				Fwd0, Fwd, Bwd1, Bwd, Fmin, Fmax, Bmin, Bmax,
-				SearchCost - 2, Cost0, Cost, Mid, HeurReq)
-		)
-	).
-
-
-	% Try applying some heuristics to see if we can avoid some work.
-:- pred myers__try_heuristics(myers_constants,
-		array(int), array(int), array(int), array(int),
-		int, int, int, int, int, int, pair(pos), pair(heur)).
-:- mode myers__try_heuristics(in, array_di, array_uo,
-		array_di, array_uo, in, in, in, in, in, out, out, out) is det.
-
-myers__try_heuristics(Constants, Fwd0, Fwd, Bwd0, Bwd,
-		Fmin, Fmax, Bmin, Bmax, Cost0, Cost, Mid, HeurReq) :-
-	Constants = constants(_, _, _, _, _, _, _, _, _, _, Heur),
-	(
-		Heur = too_expensive(Cutoff),
-		Cost0 >= Cutoff
-	->
-			% If we've done too much work, stop here.
-		Fwd = Fwd0, Bwd = Bwd0,
-		myers__too_expensive_heuristic(Constants, Fwd, Bwd,
-			Fmin, Fmax, Bmin, Bmax, Cost0, Cost, Mid, HeurReq)
-	;
-		% Can't apply heuristic, so try looking for a diff of size
-		% Cost0 + 1.
-
-		myers__find_middle_2(Constants, Fwd0, Fwd, Bwd0, Bwd,
-			Fmin, Fmax, Bmin, Bmax, Cost0 + 1, Cost, Mid, HeurReq)
-	).
+    % The best part about this algorithm is: We don't actually
+    % need to find the middle of the diff.  We only have to find
+    % an estimate to it.  If we don't find the exact middle,
+    % we will have a correct diff, but it won't necessarily be
+    % minimal.
+:- pred myers.find_middle(int::in, array(int)::in, array(int)::in, pos::in,
+    pos::in, pos::in, pos::in, heur::in, array(int)::array_di,
+    array(int)::array_uo, array(int)::array_di, array(int)::array_uo,
+    pos::out, pos::out, int::out, pair(heur)::out) is det.
+
+myers.find_middle(DOffset, FileX, FileY, Xlow, Xhigh, Ylow, Yhigh, Heur,
+        Fwd0, Fwd, Bwd0, Bwd, Xmid, Ymid, Cost, HeurReq) :-
+
+    Dmin = Xlow - Yhigh,
+    Dmax = Xhigh - Ylow,
+
+    Fmid = Xlow - Ylow,
+    array.set(Fwd0, Fmid + DOffset, Xlow, Fwd1),
+    Bmid = Xhigh - Yhigh,
+    array.set(Bwd0, Bmid + DOffset, Xhigh, Bwd1),
+
+    ( 1 = (Fmid - Bmid) /\ 1 ->
+        DeltaOdd = yes
+    ;
+        DeltaOdd = no
+    ),
+
+    Constants = constants(
+        DOffset, FileX, FileY, Xlow, Xhigh, Ylow, Yhigh,
+        Dmin, Dmax, DeltaOdd, Heur
+    ),
+
+    myers.find_middle_2(Constants, Fwd1, Fwd, Bwd1, Bwd,
+        Fmid, Fmid, Bmid, Bmid, 1, Cost, Xmid - Ymid, HeurReq).
+
+
+:- pred myers.find_middle_2(myers_constants::in,
+        array(int)::array_di, array(int)::array_uo,
+        array(int)::array_di, array(int)::array_uo,
+        int::in, int::in, int::in, int::in, int::in, int::out,
+        pair(pos)::out, pair(heur)::out) is det.
+
+myers.find_middle_2(Constants, Fwd0, Fwd, Bwd0, Bwd,
+        Fmin, Fmax, Bmin, Bmax, Cost0, Cost, Mid, HeurReq) :-
+    Constants = constants(DOffset, _, _, _, _, _, _, Dmin, Dmax, _, _),
+    ( Fmin > Dmin ->
+        Fmin1 = Fmin - 1,
+        array.set(Fwd0, Fmin1 + DOffset - 1, -1, Fwd1)
+    ;
+        Fmin1 = Fmin + 1,
+        Fwd1 = Fwd0
+    ),
+    ( Fmax < Dmax ->
+        Fmax1 = Fmax + 1,
+        array.set(Fwd1, Fmax1 + DOffset + 1, -1, Fwd2)
+    ;
+        Fmax1 = Fmax - 1,
+        Fwd2 = Fwd1
+    ),
+    myers.find_forward_reaching_path(Constants, Fwd2, Fwd, Bwd0, Bwd,
+        Fmin1, Fmax1, Bmin, Bmax, Fmax1, Cost0, Cost, Mid, HeurReq).
+
+
+:- pred myers.find_forward_reaching_path(myers_constants::in,
+        array(int)::array_di, array(int)::array_uo,
+        array(int)::array_di, array(int)::array_uo,
+        int::in, int::in, int::in, int::in, int::in, int::in,
+        int::out, pair(pos)::out, pair(heur)::out) is det.
+
+myers.find_forward_reaching_path(Constants, Fwd0, Fwd, Bwd0, Bwd,
+        Fmin, Fmax, Bmin, Bmax, SearchCost, Cost0, Cost, Mid,
+        HeurReq) :-
+    ( SearchCost < Fmin ->
+        Constants = constants(DOffset, _, _, _, _, _, _, Dmin, Dmax, _,
+                    _),
+        int.max_int(MaxInt),
+        ( Bmin > Dmin ->
+            Bmin1 = Bmin - 1,
+            array.set(Bwd0, Bmin1 + DOffset - 1, MaxInt, Bwd1)
+        ;
+            Bmin1 = Bmin + 1,
+            Bwd1 = Bwd0
+        ),
+        ( Bmax < Dmax ->
+            Bmax1 = Bmax + 1,
+            array.set(Bwd1, Bmax1 + DOffset + 1, MaxInt, Bwd2)
+        ;
+            Bmax1 = Bmax - 1,
+            Bwd2 = Bwd1
+        ),
+        myers.find_backward_reaching_path(Constants,
+            Fwd0, Fwd, Bwd2, Bwd, Fmin, Fmax, Bmin1, Bmax1,
+            Bmax1, Cost0, Cost, Mid, HeurReq)
+    ;
+        Constants = constants(DOffset, _, _, _, _, _, _, _, _, _, _),
+        array.lookup(Fwd0, SearchCost + DOffset - 1, Tlo),
+        array.lookup(Fwd0, SearchCost + DOffset + 1, Thi),
+        ( Tlo >= Thi ->
+            X0 = Tlo + 1
+        ;
+            X0 = Thi
+        ),
+        Y0 = X0 - SearchCost,
+        Constants = constants(_, FileX, FileY, _, Xhigh, _, Yhigh,
+            _, _, _, _),
+        myers.scan_forward(FileX, FileY, Xhigh, Yhigh, X0, X, Y0, Y),
+        array.set(Fwd0, SearchCost + DOffset, X, Fwd1),
+
+        Constants = constants(_, _, _, _, _, _, _, _, _, DeltaOdd, _),
+        (
+            DeltaOdd = yes,
+            Bmin =< SearchCost,
+            SearchCost =< Bmax,
+            array.lookup(Bwd0, SearchCost + DOffset, BB),
+            BB =< X
+        ->
+            Mid = X - Y,
+            Cost = 2 * Cost0 + 1,
+            Fwd = Fwd1,
+            Bwd = Bwd0,
+            HeurReq = none - none
+        ;
+            myers.find_forward_reaching_path(Constants,
+                Fwd1, Fwd, Bwd0, Bwd, Fmin, Fmax, Bmin, Bmax,
+                SearchCost - 2, Cost0, Cost, Mid, HeurReq)
+        )
+    ).
+
+
+:- pred myers.find_backward_reaching_path(myers_constants::in,
+        array(int)::array_di, array(int)::array_uo,
+        array(int)::array_di, array(int)::array_uo,
+        int::in, int::in, int::in, int::in, int::in, int::in,
+        int::out, pair(pos)::out, pair(heur)::out) is det.
+
+myers.find_backward_reaching_path(Constants, Fwd0, Fwd, Bwd0, Bwd,
+        Fmin, Fmax, Bmin, Bmax, SearchCost, Cost0, Cost, Mid,
+        HeurReq) :-
+    ( SearchCost < Bmin ->
+        myers.try_heuristics(Constants, Fwd0, Fwd, Bwd0, Bwd,
+            Fmin, Fmax, Bmin, Bmax, Cost0, Cost, Mid, HeurReq)
+    ;
+        Constants = constants(DOffset, _, _, _, _, _, _, _, _, _, _),
+        array.lookup(Bwd0, SearchCost + DOffset - 1, Tlo),
+        array.lookup(Bwd0, SearchCost + DOffset + 1, Thi),
+        ( Tlo < Thi ->
+            X0 = Tlo
+        ;
+            X0 = Thi - 1
+        ),
+        Y0 = X0 - SearchCost,
+        Constants = constants(_, FileX, FileY, Xlow, _, Ylow, _,
+            _, _, _, _),
+        myers.scan_backward(FileX, FileY, Xlow, Ylow, X0, X, Y0, Y),
+        array.set(Bwd0, SearchCost + DOffset, X, Bwd1),
+
+        Constants = constants(_, _, _, _, _, _, _, _, _, DeltaOdd, _),
+        (
+            DeltaOdd = no,
+            Fmin =< SearchCost,
+            SearchCost =< Fmax,
+            array.lookup(Fwd0, SearchCost + DOffset, FF),
+            X =< FF
+        ->
+            Mid = X - Y,
+            Cost = 2 * Cost0,
+            Fwd = Fwd0,
+            Bwd = Bwd1,
+            HeurReq = none - none
+        ;
+            myers.find_backward_reaching_path(Constants,
+                Fwd0, Fwd, Bwd1, Bwd, Fmin, Fmax, Bmin, Bmax,
+                SearchCost - 2, Cost0, Cost, Mid, HeurReq)
+        )
+    ).
+
+
+    % Try applying some heuristics to see if we can avoid some work.
+:- pred myers.try_heuristics(myers_constants::in,
+        array(int)::array_di, array(int)::array_uo,
+        array(int)::array_di, array(int)::array_uo, int::in, int::in, int::in,
+        int::in, int::in, int::out, pair(pos)::out, pair(heur)::out) is det.
+
+myers.try_heuristics(Constants, Fwd0, Fwd, Bwd0, Bwd,
+        Fmin, Fmax, Bmin, Bmax, Cost0, Cost, Mid, HeurReq) :-
+    Constants = constants(_, _, _, _, _, _, _, _, _, _, Heur),
+    (
+        Heur = too_expensive(Cutoff),
+        Cost0 >= Cutoff
+    ->
+            % If we've done too much work, stop here.
+        Fwd = Fwd0, Bwd = Bwd0,
+        myers.too_expensive_heuristic(Constants, Fwd, Bwd,
+            Fmin, Fmax, Bmin, Bmax, Cost0, Cost, Mid, HeurReq)
+    ;
+        % Can't apply heuristic, so try looking for a diff of size
+        % Cost0 + 1.
+
+        myers.find_middle_2(Constants, Fwd0, Fwd, Bwd0, Bwd,
+            Fmin, Fmax, Bmin, Bmax, Cost0 + 1, Cost, Mid, HeurReq)
+    ).

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

-	% We've done too much work, so make our best guess.
-:- pred myers__too_expensive_heuristic(myers_constants, array(int), array(int),
-		int, int, int, int, int, int, pair(pos), pair(heur)).
-:- mode myers__too_expensive_heuristic(in, array_ui, array_ui,
-		in, in, in, in, in, out, out, out) is det.
-
-myers__too_expensive_heuristic(Constants, Fwd, Bwd,
-		Fmin, Fmax, Bmin, Bmax, Cost0, Cost, Mid, HeurReq) :-
-	% Find the best diagonal that we can, take the end of
-	% that diagonal as the "middle".  Do not apply the
-	% heuristic recursively to that best diagonal.
-
-	Constants = constants(DOffset, _, _, Xlow, Xhigh, Ylow, Yhigh,
-			_, _, _, Heur),
-
-		% Find the best forward diagonal.
-	myers__find_best_forward_diagonal(Fmax, Fmin, Fwd,
-			Xhigh, Yhigh, DOffset, -1, FXYBest, 0, FXBest),
-
-		% Find the best backward diagonal.
-	int__max_int(MaxInt),
-	myers__find_best_backward_diagonal(Bmax, Bmin, Bwd,
-			Xlow, Ylow, DOffset, MaxInt, BXYBest, 0, BXBest),
-
-		% Choose which of these diagonals is the better one
-		% and return that as the "middle" point.
-	(
-		FXYBest - (Xhigh + Yhigh) < (Xlow + Ylow) - BXYBest
-	->
-		Xmid = FXBest,
-		Ymid = FXYBest - FXBest,
-		HeurReq = none - Heur
-	;
-		Xmid = BXBest,
-		Ymid = BXYBest - BXBest,
-		HeurReq = Heur - none
-	),
-	Mid = Xmid - Ymid,
-	Cost = 2 * Cost0 - 1.
-
-:- pred myers__find_best_forward_diagonal(int, int, array(int), int, int, int,
-			int, int, int, int).
-:- mode myers__find_best_forward_diagonal(in, in, array_ui, in, in, in,
-			in, out, in, out) is det.
-
-myers__find_best_forward_diagonal(D, Fmin, Fwd, Xhigh, Yhigh, DOffset,
-			FXYBest0, FXYBest, FXBest0, FXBest) :-
-	( D < Fmin ->
-		FXYBest = FXYBest0,
-		FXBest = FXBest0
-	;
-		array__lookup(Fwd, D + DOffset, X0),
-		int__min(Xhigh, X0, X1),
-		Y0 = X1 - D,
-
-		( Yhigh < Y0 ->
-			X = Yhigh + D,
-			Y = Yhigh
-		;
-			X = X1,
-			Y = Y0
-		),
-
-		NewFXY = X + Y,
-		( FXYBest0 < NewFXY ->
-			myers__find_best_forward_diagonal(D - 2, Fmin, Fwd,
-				Xhigh, Yhigh, DOffset, NewFXY, FXYBest,
-				X, FXBest)
-		;
-			myers__find_best_forward_diagonal(D - 2, Fmin, Fwd,
-				Xhigh, Yhigh, DOffset, FXYBest0, FXYBest,
-				FXBest0, FXBest)
-		)
-	).
-
-:- pred myers__find_best_backward_diagonal(int, int, array(int), int, int, int,
-			int, int, int, int).
-:- mode myers__find_best_backward_diagonal(in, in, array_ui, in, in, in,
-			in, out, in, out) is det.
-
-myers__find_best_backward_diagonal(D, Bmin, Bwd, Xlow, Ylow, DOffset,
-			BXYBest0, BXYBest, BXBest0, BXBest) :-
-	( D < Bmin ->
-		BXYBest = BXYBest0,
-		BXBest = BXBest0
-	;
-		array__lookup(Bwd, D + DOffset, X0),
-		int__max(Xlow, X0, X1),
-		Y0 = X1 - D,
-
-		( Y0 < Ylow ->
-			X = Ylow + D,
-			Y = Ylow
-		;
-			X = X1,
-			Y = Y0
-		),
-
-		NewBXY = X + Y,
-		( NewBXY < BXYBest0 ->
-			myers__find_best_backward_diagonal(D - 2, Bmin, Bwd,
-				Xlow, Ylow, DOffset, NewBXY, BXYBest,
-				X, BXBest)
-		;
-			myers__find_best_backward_diagonal(D - 2, Bmin, Bwd,
-				Xlow, Ylow, DOffset, BXYBest0, BXYBest,
-				BXBest0, BXBest)
-		)
-	).
+    % We've done too much work, so make our best guess.
+:- pred myers.too_expensive_heuristic(myers_constants::in,
+        array(int)::array_ui, array(int)::array_ui, int::in, int::in, int::in,
+        int::in, int::in, int::out, pair(pos)::out, pair(heur)::out) is det.
+
+myers.too_expensive_heuristic(Constants, Fwd, Bwd,
+        Fmin, Fmax, Bmin, Bmax, Cost0, Cost, Mid, HeurReq) :-
+    % Find the best diagonal that we can, take the end of
+    % that diagonal as the "middle".  Do not apply the
+    % heuristic recursively to that best diagonal.
+
+    Constants = constants(DOffset, _, _, Xlow, Xhigh, Ylow, Yhigh,
+            _, _, _, Heur),
+
+        % Find the best forward diagonal.
+    myers.find_best_forward_diagonal(Fmax, Fmin, Fwd,
+            Xhigh, Yhigh, DOffset, -1, FXYBest, 0, FXBest),
+
+        % Find the best backward diagonal.
+    int.max_int(MaxInt),
+    myers.find_best_backward_diagonal(Bmax, Bmin, Bwd,
+            Xlow, Ylow, DOffset, MaxInt, BXYBest, 0, BXBest),
+
+        % Choose which of these diagonals is the better one
+        % and return that as the "middle" point.
+    (
+        FXYBest - (Xhigh + Yhigh) < (Xlow + Ylow) - BXYBest
+    ->
+        Xmid = FXBest,
+        Ymid = FXYBest - FXBest,
+        HeurReq = none - Heur
+    ;
+        Xmid = BXBest,
+        Ymid = BXYBest - BXBest,
+        HeurReq = Heur - none
+    ),
+    Mid = Xmid - Ymid,
+    Cost = 2 * Cost0 - 1.
+
+:- pred myers.find_best_forward_diagonal(int::in, int::in,
+        array(int)::array_ui, int::in, int::in, int::in, int::in, int::out,
+        int::in, int::out) is det.
+
+myers.find_best_forward_diagonal(D, Fmin, Fwd, Xhigh, Yhigh, DOffset,
+            FXYBest0, FXYBest, FXBest0, FXBest) :-
+    ( D < Fmin ->
+        FXYBest = FXYBest0,
+        FXBest = FXBest0
+    ;
+        array.lookup(Fwd, D + DOffset, X0),
+        int.min(Xhigh, X0, X1),
+        Y0 = X1 - D,
+
+        ( Yhigh < Y0 ->
+            X = Yhigh + D,
+            Y = Yhigh
+        ;
+            X = X1,
+            Y = Y0
+        ),
+
+        NewFXY = X + Y,
+        ( FXYBest0 < NewFXY ->
+            myers.find_best_forward_diagonal(D - 2, Fmin, Fwd,
+                Xhigh, Yhigh, DOffset, NewFXY, FXYBest,
+                X, FXBest)
+        ;
+            myers.find_best_forward_diagonal(D - 2, Fmin, Fwd,
+                Xhigh, Yhigh, DOffset, FXYBest0, FXYBest,
+                FXBest0, FXBest)
+        )
+    ).
+
+:- pred myers.find_best_backward_diagonal(int::in, int::in,
+        array(int)::array_ui, int::in, int::in, int::in, int::in, int::out,
+        int::in, int::out) is det.
+
+myers.find_best_backward_diagonal(D, Bmin, Bwd, Xlow, Ylow, DOffset,
+            BXYBest0, BXYBest, BXBest0, BXBest) :-
+    ( D < Bmin ->
+        BXYBest = BXYBest0,
+        BXBest = BXBest0
+    ;
+        array.lookup(Bwd, D + DOffset, X0),
+        int.max(Xlow, X0, X1),
+        Y0 = X1 - D,
+
+        ( Y0 < Ylow ->
+            X = Ylow + D,
+            Y = Ylow
+        ;
+            X = X1,
+            Y = Y0
+        ),
+
+        NewBXY = X + Y,
+        ( NewBXY < BXYBest0 ->
+            myers.find_best_backward_diagonal(D - 2, Bmin, Bwd,
+                Xlow, Ylow, DOffset, NewBXY, BXYBest,
+                X, BXBest)
+        ;
+            myers.find_best_backward_diagonal(D - 2, Bmin, Bwd,
+                Xlow, Ylow, DOffset, BXYBest0, BXYBest,
+                BXBest0, BXBest)
+        )
+    ).

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

-	% Travel forwards along a snake.
-:- pred myers__scan_forward(array(int), array(int), int, int,
-		int, int, int, int).
-:- mode myers__scan_forward(in, in, in, in, in, out, in, out) is det.
-
-myers__scan_forward(FileX, FileY, Xhigh, Yhigh, Xlow0, Xlow, Ylow0, Ylow) :-
-	(
-		Xlow0 < Xhigh,
-		Ylow0 < Yhigh,
-		array__lookup(FileX, Xlow0, Line),
-		array__lookup(FileY, Ylow0, Line)
-	->
-		myers__scan_forward(FileX, FileY, Xhigh, Yhigh,
-			Xlow0 + 1, Xlow, Ylow0 + 1, Ylow)
-	;
-		Xlow = Xlow0, Ylow = Ylow0
-	).
-
-
-	% Travel backwards along a snake.
-:- pred myers__scan_backward(array(int), array(int), int, int,
-		int, int, int, int).
-:- mode myers__scan_backward(in, in, in, in, in, out, in, out) is det.
-
-myers__scan_backward(FileX, FileY, Xlow, Ylow, Xhigh0, Xhigh, Yhigh0, Yhigh) :-
-	(
-		Xhigh0 > Xlow,
-		Yhigh0 > Ylow,
-		array__lookup(FileX, Xhigh0 - 1, Line),
-		array__lookup(FileY, Yhigh0 - 1, Line)
-	->
-		myers__scan_backward(FileX, FileY, Xlow, Ylow,
-			Xhigh0 - 1, Xhigh, Yhigh0 - 1, Yhigh)
-	;
-		Xhigh = Xhigh0, Yhigh = Yhigh0
-	).
+    % Travel forwards along a snake.
+:- pred myers.scan_forward(array(int)::in, array(int)::in, int::in, int::in,
+        int::in, int::out, int::in, int::out) is det.
+
+myers.scan_forward(FileX, FileY, Xhigh, Yhigh, Xlow0, Xlow, Ylow0, Ylow) :-
+    (
+        Xlow0 < Xhigh,
+        Ylow0 < Yhigh,
+        array.lookup(FileX, Xlow0, Line),
+        array.lookup(FileY, Ylow0, Line)
+    ->
+        myers.scan_forward(FileX, FileY, Xhigh, Yhigh,
+            Xlow0 + 1, Xlow, Ylow0 + 1, Ylow)
+    ;
+        Xlow = Xlow0, Ylow = Ylow0
+    ).
+
+
+    % Travel backwards along a snake.
+:- pred myers.scan_backward(array(int)::in, array(int)::in, int::in, int::in,
+        int::in, int::out, int::in, int::out) is det.
+
+myers.scan_backward(FileX, FileY, Xlow, Ylow, Xhigh0, Xhigh, Yhigh0, Yhigh) :-
+    (
+        Xhigh0 > Xlow,
+        Yhigh0 > Ylow,
+        array.lookup(FileX, Xhigh0 - 1, Line),
+        array.lookup(FileY, Yhigh0 - 1, Line)
+    ->
+        myers.scan_backward(FileX, FileY, Xlow, Ylow,
+            Xhigh0 - 1, Xhigh, Yhigh0 - 1, Yhigh)
+    ;
+        Xhigh = Xhigh0, Yhigh = Yhigh0
+    ).

 %-----------------------------------------------------------------------------%
 %-----------------------------------------------------------------------------%
Index: samples/diff/options.m
===================================================================
RCS file: /home/mercury1/repository/mercury/samples/diff/options.m,v
retrieving revision 1.2
diff -u -r1.2 options.m
--- samples/diff/options.m	15 Sep 1998 04:54:41 -0000	1.2
+++ samples/diff/options.m	24 Apr 2006 05:48:16 -0000
@@ -1,4 +1,6 @@
 %-----------------------------------------------------------------------------%
+% vim: ft=mercury ts=4 sw=4 et
+%-----------------------------------------------------------------------------%
 % Copyright (C) 1998 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.
@@ -16,95 +18,95 @@

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

-:- pred options__get_option_ops(option_ops(option) :: out(option_ops)) is det.
+:- pred options.get_option_ops(option_ops(option) :: out(option_ops)) is det.

-	% Process the option table, perhaps returning an error message
-	% if there was some inconsistentcy or other error.
+    % Process the option table, perhaps returning an error message
+    % if there was some inconsistentcy or other error.
 :- pred postprocess_options(maybe_option_table :: in, maybe(string) :: out,
-		io__state::di, io__state::uo) is det.
+        io.state::di, io.state::uo) is det.

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

-	% Info on the accepted options, displayed in response to --help.
-:- pred options_help(io__state::di, io__state::uo) is det.
+    % Info on the accepted options, displayed in response to --help.
+:- pred options_help(io.state::di, io.state::uo) is det.

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

-:- type option_table		== option_table(option).
-:- type maybe_option_table	== maybe_option_table(option).
+:- type option_table        == option_table(option).
+:- type maybe_option_table  == maybe_option_table(option).

-	% The master list of options.
+    % The master list of options.

 :- type option --->
-	% Output styles
-	 	help
-	;	version
-	;	context	
-	;	context_style_output
-	;	unified
-	;	unified_style_output
-	;	ed
-	;	forward_ed
-	;	rcs
-	;	brief
-	;	ifdef
-	;	side_by_side
-	;	cvs_merge_conflict
-
-	% Output options
-	;	show_c_function		% Not handled (and unlikely to be soon)
-	;	show_function_line	% Not handled (and unlikely to be soon)
-	;	label
-	;	width
-	;	expand_tabs
-	;	initial_tab
-	;	paginate		% Not handled (and unlikely to be soon)
-	;	left_column
-	;	suppress_common_lines
-	;	sdiff_merge_assist	% Accepted but ignored
-
-	% Matching options
-	;	new_file		% Not handled (and unlikely to be soon)
-	;	unidirectional_new_file	% Not handled (and unlikely to be soon)
-	;	ignore_case
-	;	ignore_all_space
-	;	ignore_space_change
-
-	% Diff options
-	;	minimal
-	;	speed_large_files	% Accepted but ignored
-	;	file_split_speed_hack	% Accepted but ignored (GNU diff
-					% ignores this too, so let's not
-					% feel too bad about it)
-
-	% Change filter options
-	;	ignore_matching_lines	% Not handled (and unlikely to be soon)
-	;	ignore_blank_lines
-
-	% Directory comparison options
-	% None of these are likely to be handled in the near future.
-	;	starting_file		% Not handled
-	;	recursive		% Not handled
-	;	report_identical_files	% Not handled
-	;	exclude			% Not handled
-	;	exclude_from		% Not handled
-
-	% #ifdef format options
-	% None of these are likely to be handled in the very near future.
-	;	old_line_format		% Not handled
-	;	new_line_format		% Not handled
-	;	unchanged_line_format	% Not handled
-	;	line_format		% Not handled
-	;	old_group_format	% Not handled
-	;	new_group_format	% Not handled
-	;	unchanged_group_format	% Not handled
-	;	changed_group_format	% Not handled
-	;	horizon_lines		% Not handled
-
-	% File input options
-	% Neither of these are likely to be handled in the near future.
-	;	text			% Not handled
-	;	binary.			% Not handled
+    % Output styles
+        help
+    ;   version
+    ;   context
+    ;   context_style_output
+    ;   unified
+    ;   unified_style_output
+    ;   ed
+    ;   forward_ed
+    ;   rcs
+    ;   brief
+    ;   ifdef
+    ;   side_by_side
+    ;   cvs_merge_conflict
+
+    % Output options
+    ;   show_c_function     % Not handled (and unlikely to be soon)
+    ;   show_function_line  % Not handled (and unlikely to be soon)
+    ;   label
+    ;   width
+    ;   expand_tabs
+    ;   initial_tab
+    ;   paginate        % Not handled (and unlikely to be soon)
+    ;   left_column
+    ;   suppress_common_lines
+    ;   sdiff_merge_assist  % Accepted but ignored
+
+    % Matching options
+    ;   new_file        % Not handled (and unlikely to be soon)
+    ;   unidirectional_new_file % Not handled (and unlikely to be soon)
+    ;   ignore_case
+    ;   ignore_all_space
+    ;   ignore_space_change
+
+    % Diff options
+    ;   minimal
+    ;   speed_large_files   % Accepted but ignored
+    ;   file_split_speed_hack   % Accepted but ignored (GNU diff
+                    % ignores this too, so let's not
+                    % feel too bad about it)
+
+    % Change filter options
+    ;   ignore_matching_lines   % Not handled (and unlikely to be soon)
+    ;   ignore_blank_lines
+
+    % Directory comparison options
+    % None of these are likely to be handled in the near future.
+    ;   starting_file       % Not handled
+    ;   recursive       % Not handled
+    ;   report_identical_files  % Not handled
+    ;   exclude         % Not handled
+    ;   exclude_from        % Not handled
+
+    % #ifdef format options
+    % None of these are likely to be handled in the very near future.
+    ;   old_line_format     % Not handled
+    ;   new_line_format     % Not handled
+    ;   unchanged_line_format   % Not handled
+    ;   line_format     % Not handled
+    ;   old_group_format    % Not handled
+    ;   new_group_format    % Not handled
+    ;   unchanged_group_format  % Not handled
+    ;   changed_group_format    % Not handled
+    ;   horizon_lines       % Not handled
+
+    % File input options
+    % Neither of these are likely to be handled in the near future.
+    ;   text            % Not handled
+    ;   binary.         % Not handled

 %-----------------------------------------------------------------------------%
 %-----------------------------------------------------------------------------%
@@ -114,56 +116,56 @@
 :- import_module list, int, bool, string, map, require.

 :- pred long_option(string::in, option::out) is semidet.
-long_option("ignore-blank-lines",	ignore_blank_lines).
-long_option("context",			context).
-long_option("ifdef",			ifdef).
-long_option("show-function-line",	show_function_line).
-long_option("speed-large-files",	speed_large_files).
-long_option("ignore-matching-lines",	ignore_matching_lines).
-long_option("file-label",		label).
-long_option("label",			label).
-long_option("new-file",			new_file).
-long_option("entire-new-file",		new_file).
-long_option("unidirectional-new-file",	unidirectional_new_file).
-long_option("starting-file",		starting_file).
-long_option("initial-tab",		initial_tab).
-long_option("unified",			unified).
-long_option("width",			width).
-long_option("exclude-from",		exclude_from).
-long_option("text",			text).
-long_option("ascii",			text).
-long_option("ignore-space-change",	ignore_space_change).
-long_option("minimal",			minimal).
-long_option("ed",			ed).
-long_option("forward-ed",		forward_ed).
-long_option("ignore-case",		ignore_case).
-long_option("paginate",			paginate).
-long_option("print",			paginate).
-long_option("rcs",			rcs).
-long_option("show-c-function",		show_c_function).
-long_option("brief",			brief).
-long_option("recursive",		recursive).
-long_option("report-identical-files",	report_identical_files).
-long_option("expand-tabs",		expand_tabs).
-long_option("version",			version).
-long_option("ignore-all-space",		ignore_all_space).
-long_option("exclude",			exclude).
-long_option("side-by-side",		side_by_side).
-long_option("cvs-merge-conflict",	cvs_merge_conflict).
-long_option("left-column",		left_column).
-long_option("suppress-common-lines",	suppress_common_lines).
-long_option("sdiff-merge-assist",	sdiff_merge_assist).
-long_option("old-line-format",		old_line_format).
-long_option("new-line-format",		new_line_format).
-long_option("unchanged-line-format",	unchanged_line_format).
-long_option("line-format",		line_format).
-long_option("old-group-format",		old_group_format).
-long_option("new-group-format",		new_group_format).
-long_option("unchanged-group-format",	unchanged_group_format).
-long_option("changed-group-format",	changed_group_format).
-long_option("horizon-lines",		horizon_lines).
-long_option("help",			help).
-long_option("binary",			binary).
+long_option("ignore-blank-lines",   ignore_blank_lines).
+long_option("context",          context).
+long_option("ifdef",            ifdef).
+long_option("show-function-line",   show_function_line).
+long_option("speed-large-files",    speed_large_files).
+long_option("ignore-matching-lines",    ignore_matching_lines).
+long_option("file-label",       label).
+long_option("label",            label).
+long_option("new-file",         new_file).
+long_option("entire-new-file",      new_file).
+long_option("unidirectional-new-file",  unidirectional_new_file).
+long_option("starting-file",        starting_file).
+long_option("initial-tab",      initial_tab).
+long_option("unified",          unified).
+long_option("width",            width).
+long_option("exclude-from",     exclude_from).
+long_option("text",         text).
+long_option("ascii",            text).
+long_option("ignore-space-change",  ignore_space_change).
+long_option("minimal",          minimal).
+long_option("ed",           ed).
+long_option("forward-ed",       forward_ed).
+long_option("ignore-case",      ignore_case).
+long_option("paginate",         paginate).
+long_option("print",            paginate).
+long_option("rcs",          rcs).
+long_option("show-c-function",      show_c_function).
+long_option("brief",            brief).
+long_option("recursive",        recursive).
+long_option("report-identical-files",   report_identical_files).
+long_option("expand-tabs",      expand_tabs).
+long_option("version",          version).
+long_option("ignore-all-space",     ignore_all_space).
+long_option("exclude",          exclude).
+long_option("side-by-side",     side_by_side).
+long_option("cvs-merge-conflict",   cvs_merge_conflict).
+long_option("left-column",      left_column).
+long_option("suppress-common-lines",    suppress_common_lines).
+long_option("sdiff-merge-assist",   sdiff_merge_assist).
+long_option("old-line-format",      old_line_format).
+long_option("new-line-format",      new_line_format).
+long_option("unchanged-line-format",    unchanged_line_format).
+long_option("line-format",      line_format).
+long_option("old-group-format",     old_group_format).
+long_option("new-group-format",     new_group_format).
+long_option("unchanged-group-format",   unchanged_group_format).
+long_option("changed-group-format", changed_group_format).
+long_option("horizon-lines",        horizon_lines).
+long_option("help",         help).
+long_option("binary",           binary).

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

@@ -207,262 +209,260 @@

 :- pred option_defaults(option :: out, option_data :: out) is nondet.

-	% Output styles
-option_defaults(help,				bool(no)).
-option_defaults(version, 			bool(no)).
-option_defaults(context,			maybe_int(no)).
-option_defaults(context_style_output,		bool_special).
-option_defaults(unified,			maybe_int(no)).
-option_defaults(unified_style_output, 		bool_special).
-option_defaults(ed,				bool(no)).
-option_defaults(forward_ed,			bool(no)).
-option_defaults(rcs,				bool(no)).
-option_defaults(brief,				bool(no)).
-option_defaults(ifdef,				maybe_string(no)).
-option_defaults(side_by_side,			bool(no)).
-option_defaults(cvs_merge_conflict,		bool(no)).
-
-	% Output options
-option_defaults(show_c_function,		bool_special).
-option_defaults(show_function_line,		string_special).
-option_defaults(label,				accumulating([])).
-option_defaults(width,				int(130)).
-option_defaults(expand_tabs,			bool(no)).
-option_defaults(initial_tab,			bool(no)).
-option_defaults(paginate,			bool_special).
-option_defaults(left_column,			bool(no)).
-option_defaults(suppress_common_lines,		bool(no)).
-option_defaults(sdiff_merge_assist,		bool(no)).
-
-	% Matching options
-option_defaults(new_file,			bool_special).
-option_defaults(unidirectional_new_file,	bool_special).
-option_defaults(ignore_case,			bool(no)).
-option_defaults(ignore_all_space,		bool(no)).
-option_defaults(ignore_space_change,		bool(no)).
-
-	% Diff options
-option_defaults(minimal,			bool(no)).
-option_defaults(speed_large_files,		bool(no)).
-option_defaults(file_split_speed_hack,		bool(no)).
-
-	% Change filter options
-option_defaults(ignore_matching_lines,		string_special).
-option_defaults(ignore_blank_lines,		bool(no)).
-
-	% Directory comparison options (none of these are handled)
-option_defaults(starting_file,			string_special).
-option_defaults(recursive,			bool_special).
-option_defaults(report_identical_files,		bool_special).
-option_defaults(exclude,			string_special).
-option_defaults(exclude_from,			string_special).
-
-	% Format options (none of these are handled)
-option_defaults(old_line_format,		string_special).
-option_defaults(new_line_format,		string_special).
-option_defaults(unchanged_line_format,		string_special).
-option_defaults(line_format,			string_special).
-option_defaults(old_group_format,		string_special).
-option_defaults(new_group_format,		string_special).
-option_defaults(unchanged_group_format,		string_special).
-option_defaults(changed_group_format,		string_special).
-option_defaults(horizon_lines,			int_special).
-
-	% File input options (none of these are handled)
-option_defaults(text,				bool_special).
-option_defaults(binary,				bool_special).
+    % Output styles
+option_defaults(help,               bool(no)).
+option_defaults(version,            bool(no)).
+option_defaults(context,            maybe_int(no)).
+option_defaults(context_style_output,       bool_special).
+option_defaults(unified,            maybe_int(no)).
+option_defaults(unified_style_output,       bool_special).
+option_defaults(ed,             bool(no)).
+option_defaults(forward_ed,         bool(no)).
+option_defaults(rcs,                bool(no)).
+option_defaults(brief,              bool(no)).
+option_defaults(ifdef,              maybe_string(no)).
+option_defaults(side_by_side,           bool(no)).
+option_defaults(cvs_merge_conflict,     bool(no)).
+
+    % Output options
+option_defaults(show_c_function,        bool_special).
+option_defaults(show_function_line,     string_special).
+option_defaults(label,              accumulating([])).
+option_defaults(width,              int(130)).
+option_defaults(expand_tabs,            bool(no)).
+option_defaults(initial_tab,            bool(no)).
+option_defaults(paginate,           bool_special).
+option_defaults(left_column,            bool(no)).
+option_defaults(suppress_common_lines,      bool(no)).
+option_defaults(sdiff_merge_assist,     bool(no)).
+
+    % Matching options
+option_defaults(new_file,           bool_special).
+option_defaults(unidirectional_new_file,    bool_special).
+option_defaults(ignore_case,            bool(no)).
+option_defaults(ignore_all_space,       bool(no)).
+option_defaults(ignore_space_change,        bool(no)).
+
+    % Diff options
+option_defaults(minimal,            bool(no)).
+option_defaults(speed_large_files,      bool(no)).
+option_defaults(file_split_speed_hack,      bool(no)).
+
+    % Change filter options
+option_defaults(ignore_matching_lines,      string_special).
+option_defaults(ignore_blank_lines,     bool(no)).
+
+    % Directory comparison options (none of these are handled)
+option_defaults(starting_file,          string_special).
+option_defaults(recursive,          bool_special).
+option_defaults(report_identical_files,     bool_special).
+option_defaults(exclude,            string_special).
+option_defaults(exclude_from,           string_special).
+
+    % Format options (none of these are handled)
+option_defaults(old_line_format,        string_special).
+option_defaults(new_line_format,        string_special).
+option_defaults(unchanged_line_format,      string_special).
+option_defaults(line_format,            string_special).
+option_defaults(old_group_format,       string_special).
+option_defaults(new_group_format,       string_special).
+option_defaults(unchanged_group_format,     string_special).
+option_defaults(changed_group_format,       string_special).
+option_defaults(horizon_lines,          int_special).
+
+    % File input options (none of these are handled)
+option_defaults(text,               bool_special).
+option_defaults(binary,             bool_special).

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

 :- pred special_handler(option :: in, special_data :: in, option_table :: in,
-		maybe_option_table :: out) is semidet.
+        maybe_option_table :: out) is semidet.

 special_handler(context_style_output, bool(yes), Options0, ok(Options)) :-
-	map__lookup(Options0, context, maybe_int(Context0)),
-	( Context0 = no,
-		Context = yes(3)
-	; Context0 = yes(C),
-		Context = yes(C)
-	),
-	map__set(Options0, context, maybe_int(Context), Options).
+    map.lookup(Options0, context, maybe_int(Context0)),
+    ( Context0 = no,
+        Context = yes(3)
+    ; Context0 = yes(C),
+        Context = yes(C)
+    ),
+    map.set(Options0, context, maybe_int(Context), Options).
 special_handler(unified_style_output, bool(yes), Options0, ok(Options)) :-
-	map__lookup(Options0, unified, maybe_int(Unified0)),
-	( Unified0 = no,
-		Unified = yes(3)
-	; Unified0 = yes(C),
-		Unified = yes(C)
-	),
-	map__set(Options0, unified, maybe_int(Unified), Options).
+    map.lookup(Options0, unified, maybe_int(Unified0)),
+    ( Unified0 = no,
+        Unified = yes(3)
+    ; Unified0 = yes(C),
+        Unified = yes(C)
+    ),
+    map.set(Options0, unified, maybe_int(Unified), Options).

-	% Special handlers for unhandled options
+    % Special handlers for unhandled options
 special_handler(show_c_function, _, _, error(Msg)) :-
-	Msg = "Option not handled: --show-c-function".
+    Msg = "Option not handled: --show-c-function".
 special_handler(show_function_line, _, _, error(Msg)) :-
-	Msg = "Option not handled: --show-function-line".
+    Msg = "Option not handled: --show-function-line".
 special_handler(paginate, _, _, error(Msg)) :-
-	Msg = "Option not handled: --paginate".
+    Msg = "Option not handled: --paginate".
 special_handler(sdiff_merge_assist, _, _, error(Msg)) :-
-	Msg = "Option not handled: --sdiff-merge-assist".
+    Msg = "Option not handled: --sdiff-merge-assist".
 special_handler(new_file, _, _, error(Msg)) :-
-	Msg = "Option not handled: --new-file".
+    Msg = "Option not handled: --new-file".
 special_handler(unidirectional_new_file, _, _, error(Msg)) :-
-	Msg = "Option not handled: --unidirectional-new-file".
+    Msg = "Option not handled: --unidirectional-new-file".
 special_handler(speed_large_files, _, _, error(Msg)) :-
-	Msg = "Option not handled: --speed-large-files".
+    Msg = "Option not handled: --speed-large-files".
 special_handler(ignore_matching_lines, _, _, error(Msg)) :-
-	Msg = "Option not handled: --ignore-matching-lines".
+    Msg = "Option not handled: --ignore-matching-lines".
 special_handler(ignore_blank_lines, _, _, error(Msg)) :-
-	Msg = "Option not handled: --ignore-blank-lines".
+    Msg = "Option not handled: --ignore-blank-lines".
 special_handler(starting_file, _, _, error(Msg)) :-
-	Msg = "Option not handled: --starting-file".
+    Msg = "Option not handled: --starting-file".
 special_handler(recursive, _, _, error(Msg)) :-
-	Msg = "Option not handled: --recursive".
+    Msg = "Option not handled: --recursive".
 special_handler(report_identical_files, _, _, error(Msg)) :-
-	Msg = "Option not handled: --report-identical-files".
+    Msg = "Option not handled: --report-identical-files".
 special_handler(exclude, _, _, error(Msg)) :-
-	Msg = "Option not handled: --exclude".
+    Msg = "Option not handled: --exclude".
 special_handler(exclude_from, _, _, error(Msg)) :-
-	Msg = "Option not handled: --exclude-from".
+    Msg = "Option not handled: --exclude-from".
 special_handler(old_line_format, _, _, error(Msg)) :-
-	Msg = "Option not handled: --old-line-format".
+    Msg = "Option not handled: --old-line-format".
 special_handler(new_line_format, _, _, error(Msg)) :-
-	Msg = "Option not handled: --new-line-format".
+    Msg = "Option not handled: --new-line-format".
 special_handler(unchanged_line_format, _, _, error(Msg)) :-
-	Msg = "Option not handled: --unchangedline-format".
+    Msg = "Option not handled: --unchangedline-format".
 special_handler(line_format, _, _, error(Msg)) :-
-	Msg = "Option not handled: --line-format".
+    Msg = "Option not handled: --line-format".
 special_handler(old_group_format, _, _, error(Msg)) :-
-	Msg = "Option not handled: --old-group-format".
+    Msg = "Option not handled: --old-group-format".
 special_handler(new_group_format, _, _, error(Msg)) :-
-	Msg = "Option not handled: --new-group-format".
+    Msg = "Option not handled: --new-group-format".
 special_handler(unchanged_group_format, _, _, error(Msg)) :-
-	Msg = "Option not handled: --unchanged-group-format".
+    Msg = "Option not handled: --unchanged-group-format".
 special_handler(changed_group_format, _, _, error(Msg)) :-
-	Msg = "Option not handled: --changed-group-format".
+    Msg = "Option not handled: --changed-group-format".
 special_handler(horizon_lines, _, _, error(Msg)) :-
-	Msg = "Option not handled: --horizon-lines".
+    Msg = "Option not handled: --horizon-lines".
 special_handler(text, _, _, error(Msg)) :-
-	Msg = "Option not handled: --text".
+    Msg = "Option not handled: --text".
 special_handler(binary, _, _, error(Msg)) :-
-	Msg = "Option not handled: --binary".
+    Msg = "Option not handled: --binary".

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

-options__get_option_ops(OptionOps) :-
-	OptionOps = option_ops(
-		short_option,
-		long_option,
-		option_defaults,
-		special_handler
-	).
+options.get_option_ops(OptionOps) :-
+    OptionOps = option_ops(
+        short_option,
+        long_option,
+        option_defaults,
+        special_handler
+    ).

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

-	% Postprocess the options
-postprocess_options(ok(OptionTable0), Result) -->
-	( { postprocess_output_style(OptionTable0, OutputStyle) } ->
-		globals__io_init(OptionTable0),
-		globals__io_set_output_style(OutputStyle),
-		{ Result = no }
-	;
-		{ Result = yes("Can't set more than one output style.") }
-	).
-postprocess_options(error(Msg), yes(Msg)) --> [].
+    % Postprocess the options
+postprocess_options(ok(OptionTable0), Result, !IO) :-
+    ( postprocess_output_style(OptionTable0, OutputStyle) ->
+        globals.io_init(OptionTable0, !IO),
+        globals.io_set_output_style(OutputStyle, !IO),
+        Result = no
+    ;
+        Result = yes("Can't set more than one output style.")
+    ).
+postprocess_options(error(Msg), yes(Msg), !IO).

-	% Determine which output style to use from the provided
-	% options.
+    % Determine which output style to use from the provided
+    % options.
 :- pred postprocess_output_style(option_table :: in,
-		diff_out__output_style :: out) is semidet.
+        diff_out.output_style :: out) is semidet.

 postprocess_output_style(OptionTable, Style) :-
-	(
-		map__search(OptionTable, help, bool(UseHelp)),
-		map__search(OptionTable, version, bool(UseVersion)),
-		map__search(OptionTable, context, maybe_int(UseContext)),
-		map__search(OptionTable, unified, maybe_int(UseUnified)),
-		map__search(OptionTable, ed, bool(UseEd)),
-		map__search(OptionTable, forward_ed, bool(UseForwardEd)),
-		map__search(OptionTable, rcs, bool(UseRCS)),
-		map__search(OptionTable, brief, bool(UseBrief)),
-		map__search(OptionTable, ifdef, maybe_string(UseIfdef)),
-		map__search(OptionTable, side_by_side, bool(UseSideBySide)),
-		map__search(OptionTable, cvs_merge_conflict, bool(CVS))
-	->
-		postprocess_output_style_2(UseHelp, UseVersion, UseContext,
-			UseUnified, UseEd, UseForwardEd, UseRCS, UseBrief,
-			UseIfdef, UseSideBySide, CVS,
-			Style)
-	;
-		error("postprocess_output_style")
-	).
-
-:- pred postprocess_output_style_2(bool, bool, maybe(int), maybe(int), bool,
-		bool, bool, bool, maybe(string), bool, bool,
-		diff_out__output_style).
-:- mode postprocess_output_style_2(in, in, in, in, in, in, in, in, in, in, in,
-		out) is semidet.
-
+    (
+        map.search(OptionTable, help, bool(UseHelp)),
+        map.search(OptionTable, version, bool(UseVersion)),
+        map.search(OptionTable, context, maybe_int(UseContext)),
+        map.search(OptionTable, unified, maybe_int(UseUnified)),
+        map.search(OptionTable, ed, bool(UseEd)),
+        map.search(OptionTable, forward_ed, bool(UseForwardEd)),
+        map.search(OptionTable, rcs, bool(UseRCS)),
+        map.search(OptionTable, brief, bool(UseBrief)),
+        map.search(OptionTable, ifdef, maybe_string(UseIfdef)),
+        map.search(OptionTable, side_by_side, bool(UseSideBySide)),
+        map.search(OptionTable, cvs_merge_conflict, bool(CVS))
+    ->
+        postprocess_output_style_2(UseHelp, UseVersion, UseContext,
+            UseUnified, UseEd, UseForwardEd, UseRCS, UseBrief,
+            UseIfdef, UseSideBySide, CVS,
+            Style)
+    ;
+        error("postprocess_output_style")
+    ).
+
+:- pred postprocess_output_style_2(bool::in, bool::in, maybe(int)::in,
+        maybe(int)::in, bool::in, bool::in, bool::in, bool::in,
+        maybe(string)::in, bool::in, bool::in,
+        diff_out.output_style::out) is semidet.
 postprocess_output_style_2(no, no, no, no, no, no, no, no, no, no, no,
-					normal).
+                    normal).
 postprocess_output_style_2(yes, no, no, no, no, no, no, no, no, no, no,
-					help_only).
+                    help_only).
 postprocess_output_style_2(no, yes, no, no, no, no, no, no, no, no, no,
-					version_only).
+                    version_only).
 postprocess_output_style_2(no, no, yes(C), no, no, no, no, no, no, no, no,
-					context(C)).
+                    context(C)).
 postprocess_output_style_2(no, no, no, yes(U), no, no, no, no, no, no, no,
-					unified(U)).
+                    unified(U)).
 postprocess_output_style_2(no, no, no, no, yes, no, no, no, no, no, no,
-					ed).
+                    ed).
 postprocess_output_style_2(no, no, no, no, no, yes, no, no, no, no, no,
-					forward_ed).
+                    forward_ed).
 postprocess_output_style_2(no, no, no, no, no, no, yes, no, no, no, no,
-					rcs).
+                    rcs).
 postprocess_output_style_2(no, no, no, no, no, no, no, yes, no, no, no,
-					brief).
+                    brief).
 postprocess_output_style_2(no, no, no, no, no, no, no, no, yes(Sym), no, no,
-					ifdef(Sym)).
+                    ifdef(Sym)).
 postprocess_output_style_2(no, no, no, no, no, no, no, no, no, yes, no,
-					side_by_side).
+                    side_by_side).
 postprocess_output_style_2(no, no, no, no, no, no, no, no, no, no, yes,
-					cvs_merge_conflict).
+                    cvs_merge_conflict).

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

-	% Help text for the options.
-options_help -->
-	io__write_string("Output styles:\n"),
-	io__write_string("\t--help\n"),
-	io__write_string("\t\tOutput this help.\n"),
-	io__write_string("\t-v, --version\n"),
-	io__write_string("\t\tOutput version info.\n"),
-	io__write_string("\t-c, -C <num>, --context <num>\n"),
-	io__write_string("\t\tOutput <num> (default 2) lines of copied context.\n"),
-	io__write_string("\t-u, -U <num>, --unified <num>\n"),
-	io__write_string("\t\tOutput <num> (default 2) lines of unified context.\n"),
-	io__write_string("\t\t-L <label>, --label <label>  Use <label>
instead of file name.\n"),
-	io__write_string("\t-e, --ed\n"),
-	io__write_string("\t\tOutput an ed script.\n"),
-	io__write_string("\t-f, --forward-ed\n"),
-	io__write_string("\t\tProduce output similar to --ed, not useful to
ed(1),\n"),
-	io__write_string("\t\tand in the opposite order.\n"),
-	io__write_string("\t-n, --rcs\n"),
-	io__write_string("\t\tOutput an RCS format diff.\n"),
-	io__write_string("\t-q, --brief\n"),
-	io__write_string("\t\tOutput only whether or not files differ.\n"),
-	io__write_string("\t-D <name>, --ifdef <name>\n"),
-	io__write_string("\t\tProduce output in #ifdef <name> format.\n"),
-	io__write_string("\t-y, --side-by-side\n"),
-	io__write_string("\t\tProduce output in side-by-side format.\n"),
-	io__write_string("\t\t-w <num>, --width <num>  Output at most <num>
(default 130)\n"),
-	io__write_string("\t\t\tcharacters per line.\n"),
-	io__write_string("\t\t--left-column  Output only the left column of
common lines.\n"),
-	io__write_string("\t\t--suppress-common-lines  Do not output common
lines.\n"),
-	io__write_string("\nMatching options:\n"),
-	io__write_string("\t-d, --minimal\n"),
-	io__write_string("\t\tTry hard to find as small a set of changes as
possible.\n"),
-	io__write_string("\t-B, --ignore-blank-lines\n"),
-	io__write_string("\t\tIgnore changes whose lines are all blank.\n").
+    % Help text for the options.
+options_help(!IO) :-
+    io.write_string("Output styles:\n", !IO),
+    io.write_string("\t--help\n", !IO),
+    io.write_string("\t\tOutput this help.\n", !IO),
+    io.write_string("\t-v, --version\n", !IO),
+    io.write_string("\t\tOutput version info.\n", !IO),
+    io.write_string("\t-c, -C <num>, --context <num>\n", !IO),
+    io.write_string("\t\tOutput <num> (default 2) lines of copied
context.\n", !IO),
+    io.write_string("\t-u, -U <num>, --unified <num>\n", !IO),
+    io.write_string("\t\tOutput <num> (default 2) lines of unified
context.\n", !IO),
+    io.write_string("\t\t-L <label>, --label <label>  Use <label>
instead of file name.\n", !IO),
+    io.write_string("\t-e, --ed\n", !IO),
+    io.write_string("\t\tOutput an ed script.\n", !IO),
+    io.write_string("\t-f, --forward-ed\n", !IO),
+    io.write_string("\t\tProduce output similar to --ed, not useful
to ed(1),\n", !IO),
+    io.write_string("\t\tand in the opposite order.\n", !IO),
+    io.write_string("\t-n, --rcs\n", !IO),
+    io.write_string("\t\tOutput an RCS format diff.\n", !IO),
+    io.write_string("\t-q, --brief\n", !IO),
+    io.write_string("\t\tOutput only whether or not files differ.\n", !IO),
+    io.write_string("\t-D <name>, --ifdef <name>\n", !IO),
+    io.write_string("\t\tProduce output in #ifdef <name> format.\n", !IO),
+    io.write_string("\t-y, --side-by-side\n", !IO),
+    io.write_string("\t\tProduce output in side-by-side format.\n", !IO),
+    io.write_string("\t\t-w <num>, --width <num>  Output at most
<num> (default 130)\n", !IO),
+    io.write_string("\t\t\tcharacters per line.\n", !IO),
+    io.write_string("\t\t--left-column  Output only the left column
of common lines.\n", !IO),
+    io.write_string("\t\t--suppress-common-lines  Do not output
common lines.\n", !IO),
+    io.write_string("\nMatching options:\n", !IO),
+    io.write_string("\t-d, --minimal\n", !IO),
+    io.write_string("\t\tTry hard to find as small a set of changes
as possible.\n", !IO),
+    io.write_string("\t-B, --ignore-blank-lines\n", !IO),
+    io.write_string("\t\tIgnore changes whose lines are all blank.\n", !IO).

 %-----------------------------------------------------------------------------%
 %-----------------------------------------------------------------------------%
Index: samples/rot13/rot13_concise.m
===================================================================
RCS file: /home/mercury1/repository/mercury/samples/rot13/rot13_concise.m,v
retrieving revision 1.1
diff -u -r1.1 rot13_concise.m
--- samples/rot13/rot13_concise.m	19 Nov 1998 06:18:21 -0000	1.1
+++ samples/rot13/rot13_concise.m	24 Apr 2006 05:48:16 -0000
@@ -1,3 +1,6 @@
+%-----------------------------------------------------------------------------%
+% vim: ft=mercury ts=4 sw=4 et
+%-----------------------------------------------------------------------------%
 % File: rot13_concise.m
 % Main authors: Warwick Harvey <wharvey at cs.monash.edu.au>
 %               Fergus Henderson <fjh at cs.mu.oz.au>
@@ -20,8 +23,7 @@
 :- interface.
 :- import_module io.

-:- pred main(state, state).
-:- mode main(di, uo) is det.
+:- pred main(state::di, state::uo) is det.

 :- implementation.
 :- import_module char, int, string.
@@ -31,28 +33,28 @@
 cycle = 26.

 rot_n(N, Char) = RotChar :-
-	char_to_string(Char, CharString),
-	( if sub_string_search(alphabet, CharString, Index) then
-		NewIndex = (Index + N) mod cycle + cycle * (Index // cycle),
-		index_det(alphabet, NewIndex, RotChar)
-	else
-		RotChar = Char
-	).
+    char_to_string(Char, CharString),
+    ( if sub_string_search(alphabet, CharString, Index) then
+        NewIndex = (Index + N) mod cycle + cycle * (Index // cycle),
+        index_det(alphabet, NewIndex, RotChar)
+    else
+        RotChar = Char
+    ).

 rot13(Char) = rot_n(13, Char).

-main -->
-	read_char(Res),
-	( { Res = ok(Char) },
-		print(rot13(Char)),
-		main
-	; { Res = eof }
-	; { Res = error(ErrorCode) },
-		{ error_message(ErrorCode, ErrorMessage) },
-		stderr_stream(StdErr),
-		print(StdErr, "rot13: error reading input: "),
-		print(StdErr, ErrorMessage),
-		nl(StdErr)
-	).
+main(!IO) :-
+    read_char(Res, !IO),
+    ( Res = ok(Char),
+        print(rot13(Char), !IO),
+        main(!IO)
+    ; Res = eof
+    ; Res = error(ErrorCode),
+        error_message(ErrorCode, ErrorMessage),
+        stderr_stream(StdErr, !IO),
+        print(StdErr, "rot13: error reading input: ", !IO),
+        print(StdErr, ErrorMessage, !IO),
+        nl(StdErr, !IO)
+    ).


Index: samples/rot13/rot13_gustavo.m
===================================================================
RCS file: /home/mercury1/repository/mercury/samples/rot13/rot13_gustavo.m,v
retrieving revision 1.1
diff -u -r1.1 rot13_gustavo.m
--- samples/rot13/rot13_gustavo.m	19 Nov 1998 06:18:22 -0000	1.1
+++ samples/rot13/rot13_gustavo.m	24 Apr 2006 05:48:16 -0000
@@ -1,3 +1,6 @@
+%-----------------------------------------------------------------------------%
+% vim: ft=mercury ts=4 sw=4 et
+%-----------------------------------------------------------------------------%
 % I have another version of rot13.
 %
 % Gustavo A. Ospina <g-ospina at uniandes.edu.co>
@@ -7,7 +10,7 @@
 % on your char library. Maybe my version is slower, but it can be discussed.
 %
 % This source file is hereby placed in the public domain.
-%	- Gustavo Ospina
+%   - Gustavo Ospina

 :- module rot13_gustavo.

@@ -15,7 +18,7 @@

 :- import_module io.

-:- pred main(io__state::di,io__state::uo) is det.
+:- pred main(io.state::di,io.state::uo) is det.

 :- implementation.

@@ -24,10 +27,10 @@
 :- pred rot13(char::in,char::out) is det.

 rot13(Char,RotChar) :-
-    char__is_upper(Char) ->
+    char.is_upper(Char) ->
         rot13(Char,0'A,RotChar)
     ;
-    char__is_lower(Char) ->
+    char.is_lower(Char) ->
         rot13(Char,0'a,RotChar)
     ;
     RotChar = Char.
@@ -35,38 +38,38 @@
 :- pred rot13(char::in,int::in,char::out) is det.

 rot13(Char,CodeLetterA,RotChar) :-
-    char__to_int(Char,CodeChar),
+    char.to_int(Char,CodeChar),
     RotCode = (CodeChar - CodeLetterA + 13) mod 26 + CodeLetterA,
-    char__to_int(RChar,RotCode) ->
+    char.to_int(RChar,RotCode) ->
         RotChar = RChar
     ;
         RotChar = '\a'.
         /* Alert character (Error case. To satisfy mode check) */

-:- pred printRotChars(list(char)::in,io__state::di,io__state::uo) is det.
+:- pred printRotChars(list(char)::in,io.state::di,io.state::uo) is det.

-printRotChars([]) -->
-    [].
+printRotChars([], !IO) :-
+    true.

-printRotChars([Ch|Chs]) -->
-    {rot13(Ch,RotCh)},
-    io__write_char(RotCh),
-    printRotChars(Chs).
+printRotChars([Ch|Chs], !IO) :-
+    rot13(Ch,RotCh),
+    io.write_char(RotCh, !IO),
+    printRotChars(Chs, !IO).

 % Main Program

-main -->
-    io__read_line(Result),
+main(!IO) :-
+    io.read_line(Result, !IO),
     (
-        {Result = ok(Line)},
-        printRotChars(Line),
-	main
+        Result = ok(Line),
+        printRotChars(Line, !IO),
+    main(!IO)
     ;
-        {Result = eof,
-        true}
+        Result = eof,
+        true
     ;
-        {Result = error(Error),
-        io__error_message(Error,Message)},
-        io__stderr_stream(Stderr),
-        io__write_string(Stderr,Message)
+        Result = error(Error),
+        io.error_message(Error,Message),
+        io.stderr_stream(Stderr, !IO),
+        io.write_string(Stderr,Message, !IO)
     ).
Index: samples/rot13/rot13_juergen.m
===================================================================
RCS file: /home/mercury1/repository/mercury/samples/rot13/rot13_juergen.m,v
retrieving revision 1.1
diff -u -r1.1 rot13_juergen.m
--- samples/rot13/rot13_juergen.m	19 Nov 1998 06:18:23 -0000	1.1
+++ samples/rot13/rot13_juergen.m	24 Apr 2006 05:48:16 -0000
@@ -1,38 +1,41 @@
+%-----------------------------------------------------------------------------%
+% vim: ft=mercury ts=4 sw=4 et
+%-----------------------------------------------------------------------------%
 %
 % Copyright (C) 1998 Jürgen Stuber <juergen at mpi-sb.mpg.de>
 % This file may only be copied under the terms of the GNU General
 % Public License - see the file COPYING in the Mercury distribution.
 %
 % I couldn't resist:
-% 	Jürgen Stuber <juergen at mpi-sb.mpg.de>
-% 	http://www.mpi-sb.mpg.de/~juergen/
+%   Jürgen Stuber <juergen at mpi-sb.mpg.de>
+%   http://www.mpi-sb.mpg.de/~juergen/

 :- module rot13_juergen.
 :- interface.
 :- import_module io.

-:- pred main(io__state::di, io__state::uo) is det.
+:- pred main(io.state::di, io.state::uo) is det.

 :- implementation.
 :- import_module char, int, require.

 :- pred rot13( char::in, char::out) is det.

-main -->
-    io__read_char( Result ),
-    ( { Result = ok( Char ) } ->
-        { rot13( Char, Rot13Char ) },
-	io__write_char( Rot13Char ),
-        main
+main(!IO) :-
+    io.read_char( Result, !IO ),
+    ( Result = ok( Char ) ->
+        rot13( Char, Rot13Char ),
+    io.write_char( Rot13Char, !IO ),
+        main(!IO)

-    ; { Result = eof } ->
-        { true }
+    ; Result = eof ->
+        true
     ;
-	{ error( "read failed" ) }
+    error( "read failed" )
     ).

 rot13( Char, Rot13Char ) :-
-    char__to_int( Char, Code ),
+    char.to_int( Char, Code ),
     ( 0'A =< Code, Code =< 0'Z ->
         Rot13Code = (Code - 0'A + 13) mod 26 + 0'A
     ; 0'a =< Code, Code =< 0'z ->
@@ -40,7 +43,7 @@
     ;
         Rot13Code = Code
     ),
-    ( char__to_int( Ch, Rot13Code ) ->
+    ( char.to_int( Ch, Rot13Code ) ->
                 Rot13Char = Ch
     ;
                 error("too offensive, censored")
Index: samples/rot13/rot13_ralph.m
===================================================================
RCS file: /home/mercury1/repository/mercury/samples/rot13/rot13_ralph.m,v
retrieving revision 1.1
diff -u -r1.1 rot13_ralph.m
--- samples/rot13/rot13_ralph.m	31 Jan 2001 09:22:07 -0000	1.1
+++ samples/rot13/rot13_ralph.m	24 Apr 2006 05:48:16 -0000
@@ -16,7 +16,7 @@



-:- pred main(io__state::di, io__state::uo) is det.
+:- pred main(io.state::di, io.state::uo) is det.

 % ----------------------------------------------------------------------------
%
 % ----------------------------------------------------------------------------
%
@@ -27,11 +27,11 @@

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

-main -->
-    io__read_byte(Result),
-    (   { Result = ok(X) },         io__write_byte(rot13(X)), main
-    ;   { Result = eof }
-    ;   { Result = error(ErrNo)},   { error(io__error_message(ErrNo)) }
+main(!IO) :-
+    io.read_byte(Result, !IO),
+    (   Result = ok(X),         io.write_byte(rot13(X), !IO), main(!IO)
+    ;   Result = eof
+    ;   Result = error(ErrNo),   error(io.error_message(ErrNo))
     ).

 % ----------------------------------------------------------------------------
%
Index: samples/rot13/rot13_verbose.m
===================================================================
RCS file: /home/mercury1/repository/mercury/samples/rot13/rot13_verbose.m,v
retrieving revision 1.1
diff -u -r1.1 rot13_verbose.m
--- samples/rot13/rot13_verbose.m	19 Nov 1998 06:18:23 -0000	1.1
+++ samples/rot13/rot13_verbose.m	24 Apr 2006 05:48:16 -0000
@@ -1,3 +1,6 @@
+%-----------------------------------------------------------------------------%
+% vim: ft=mercury ts=4 sw=4 et
+%-----------------------------------------------------------------------------%
 % File: rot13_verbose.m
 % Main author: Warwick Harvey <wharvey at cs.monash.edu.au>
 % Additional input: Fergus Henderson <fjh at cs.mu.oz.au>
@@ -22,17 +25,15 @@
 :- interface.
 :- import_module io.

-:- pred main(io__state, io__state).
-:- mode main(di, uo) is det.
+:- pred main(io.state::di, io.state::uo) is det.

 :- implementation.
 :- import_module char, int, require.

-	% rot13a/2
-	% A table to map the alphabetic characters to their rot13 equivalents
-	% (fails if the input is not alphabetic).
-:- pred rot13a(char, char).
-:- mode rot13a(in, out) is semidet.
+    % rot13a/2
+    % A table to map the alphabetic characters to their rot13 equivalents
+    % (fails if the input is not alphabetic).
+:- pred rot13a(char::in, char::out) is semidet.

 rot13a('a', 'n').
 rot13a('b', 'o').
@@ -87,30 +88,29 @@
 rot13a('Y', 'L').
 rot13a('Z', 'M').

-	% rot13/2
-	% Applies the rot13 algorithm to a character.
-:- pred rot13(char, char).
-:- mode rot13(in, out) is det.
+    % rot13/2
+    % Applies the rot13 algorithm to a character.
+:- pred rot13(char::in, char::out) is det.

 rot13(Char, RotChar) :-
-	( if rot13a(Char, TmpChar) then
-		RotChar = TmpChar
-	else
-		RotChar = Char
-	).
-
-main -->
-	io__read_char(Res),
-	( { Res = ok(Char) },
-		{ rot13(Char, RotChar) },
-		io__write_char(RotChar),
-		main
-	; { Res = eof }
-	; { Res = error(ErrorCode) },
-		{ io__error_message(ErrorCode, ErrorMessage) },
-		io__stderr_stream(StdErr),
-		io__write_string(StdErr, "rot13: error reading input: "),
-		io__write_string(StdErr, ErrorMessage),
-		io__nl(StdErr)
-	).
+    ( if rot13a(Char, TmpChar) then
+        RotChar = TmpChar
+    else
+        RotChar = Char
+    ).
+
+main(!IO) :-
+    io.read_char(Res, !IO),
+    ( Res = ok(Char),
+        rot13(Char, RotChar),
+        io.write_char(RotChar, !IO),
+        main(!IO)
+    ; Res = eof
+    ; Res = error(ErrorCode),
+        io.error_message(ErrorCode, ErrorMessage),
+        io.stderr_stream(StdErr, !IO),
+        io.write_string(StdErr, "rot13: error reading input: ", !IO),
+        io.write_string(StdErr, ErrorMessage, !IO),
+        io.nl(StdErr, !IO)
+    ).

--------------------------------------------------------------------------
mercury-reviews mailing list
post:  mercury-reviews at cs.mu.oz.au
administrative address: owner-mercury-reviews at cs.mu.oz.au
unsubscribe: Address: mercury-reviews-request at cs.mu.oz.au Message: unsubscribe
subscribe:   Address: mercury-reviews-request at cs.mu.oz.au Message: subscribe
--------------------------------------------------------------------------



More information about the reviews mailing list