[m-rev.] For review: State Variables

Ralph Becket rafe at cs.mu.OZ.AU
Thu Jun 27 11:37:11 AEST 2002


Simon Taylor, Thursday, 27 June 2002:
> On 25-Jun-2002, Ralph Becket <rafe at cs.mu.OZ.AU> wrote:
> > diff -u make_hlds.m make_hlds.m
> > --- make_hlds.m	7 Jun 2002 07:39:12 -0000
> > +++ make_hlds.m	25 Jun 2002 06:45:05 -0000
> > @@ -16,9 +16,6 @@
> >  % super-homogenous form, and introduce implicit quantification.
> >  % 
> >  % XXX we should record each error using module_info_incr_errors.
> > -%
> > -% XXX For state variables, we should allow quantifiers around if-then-else
> > -% expressions.
> 
> You still haven't handled quantification for if-then-else goals.
> It's fine to do that as a separate change immediately after you commit.

Well, it works!  But I've just realized I hadn't submitted the requisite
diff for prog_io_goal.m which is involved; parse_some_vars_goal now
wraps the quantified goal with some_state_vars/2 if the quantifier
includes state variables.  The state variable code for handling
if-then-else expressions has been changed to allow these state variables
to scope over the then-goal as well as the condition (see
prepare_for_if_then_else_expr and friends.)

Index: prog_io_goal.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/prog_io_goal.m,v
retrieving revision 1.22
diff -u -r1.22 prog_io_goal.m
--- prog_io_goal.m	20 Mar 2002 12:37:13 -0000	1.22
+++ prog_io_goal.m	25 Jun 2002 04:47:46 -0000
@@ -257,18 +299,21 @@
 		A = call(unqualified(PurityString), [A2], pure)
 	).
 
-
 %-----------------------------------------------------------------------------%
 
 parse_some_vars_goal(A0, VarSet0, Vars, A, VarSet) :-
 	( 
-		A0 = term__functor(term__atom("some"), [Vars0, A1], _Context),
-		parse_list_of_vars(Vars0, Vars1)
+		A0 = term__functor(term__atom("some"), [QVars, A1], Context),
+		parse_quantifier_vars(QVars, StateVars0, Vars0)
 	->
-		list__map(term__coerce_var, Vars1, Vars),
-		parse_goal(A1, VarSet0, A, VarSet)
+		list__map(term__coerce_var, StateVars0, StateVars),
+		list__map(term__coerce_var, Vars0,      Vars),
+		parse_goal(A1, VarSet0, A2, VarSet),
+		A = ( if   StateVars \= []
+		      then some_state_vars(StateVars, A2) - Context
+		      else A2 )
 	;
-		Vars = [],
+		Vars      = [],
 		parse_goal(A0, VarSet0, A, VarSet)
 	).

> > +	% We implement a special purpose comparison for state variable
> > +	% names that compares the numbers appended at the right hand
> > +	% ends of the name strings.
> > +	%
> > +	% NOTE state variable names are either "..._X" or "..._X_N"
> > +	% where X is the name of the program variable used for the
> > +	% state variable and N is a decimal number with no leading
> > +	% zeroes.
> > +	%
> > +:- pred compare_svar_names(comparison_result, string, string).
> > +:- mode compare_svar_names(out, in, in) is det.
> > +
> > +compare_svar_names(R, A, B) :-
> > +	csvns_1(R, 1, A, length(A), B, length(B)).
> 
> > +	% First find the start of the numbers at the right hand end, if
> > +	% present.
> > +	%
> > +:- pred csvns_1(comparison_result, int, string, int, string, int).
> > +:- mode csvns_1(out, in, in, in, in, in) is det.
> 
> Please don't abbreviate like that.

Sorry.  See below...

> > +csvns_1(R, I, A, MaxA, B, MaxB) :-
> > +	( if I < MaxA, I < MaxB then
> > +		X = A `unsafe_index` (MaxA - I),
> > +		Y = B `unsafe_index` (MaxB - I),
> > +		( if is_digit(X), is_digit(Y)      then
> > +			csvns_1(R, I + 1, A, MaxA, B, MaxB)
> > +		  else if X = ('_'),   is_digit(Y) then
> > +		  	R = (<)
> > +		  else if is_digit(X), Y = ('_')   then
> > +		  	R = (>)
> > +		  else if X = ('_'),   Y = ('_')   then
> > +		  	csvns_2(R, I - 1, A, MaxA, B, MaxB)
> > +		  else if X = Y                    then
> > +		  	R = (=)
> > +		  else
> > +			error("make_hlds__compare_svar_names: \
> > +names are not in expected format")
> > +		)
> > +	  else
> > +		error("make_hlds__compare_svar_names: \
> > +names are not in expected format")
> > +	).
> > +
> > +
> > +	% Decide the greater of the two numbers at the right hand end
> > +	% (both numbers will have the same number of digits.)
> > +	%
> > +:- pred csvns_2(comparison_result, int, string, int, string, int).
> > +:- mode csvns_2(out, in, in, in, in, in) is det.
> > +
> > +csvns_2(R, I, A, MaxA, B, MaxB) :-
> > +	( if 0 < I then
> > +		X = A `unsafe_index` (MaxA - I) `with_type` char,
> > +		Y = B `unsafe_index` (MaxB - I) `with_type` char,
> > +		compare(RXY, X, Y),
> > +		(	RXY = (<),	R = (<)
> > +		;	RXY = (=),	csvns_2(R, I - 1, A, MaxA, B, MaxB)
> > +		;	RXY = (>),	R = (>)
> > +		)
> > +	  else
> > +	  	R = (=)
> > +	).
> 
> This looks over-complicated to me. Wouldn't it be simpler to
> write a predicate to parse the trailing integer of a string,
> and then just compare the results.

Good idea.  Changed to...

+:- pred compare_svar_names(comparison_result, string, string).
+:- mode compare_svar_names(out, in, in) is det.
+ 
+compare_svar_names(R, A, B) :-
+        compare(R, int_suffix_of(A), int_suffix_of(B)).
+ 
+ 
+        % Find the number suffix at the end of a string as an int.
+        %
+:- func int_suffix_of(string) = int.
+ 
+int_suffix_of(S) = int_suffix_2(S, length(S) - 1, 1, 0).
+ 
+ 
+        % int_suffix_2(String, Index, RadixOfIndexDigit, IntSoFar) = IntSuffix
+        %
+:- func int_suffix_2(string, int, int, int) = int.
+ 
+int_suffix_2(S, I, R, N) =
+        ( if
+                0 =< I,
+                digit_to_int(S `unsafe_index` I, D),
+                D  < 10
+          then
+                int_suffix_2(S, I - 1, 10 * R, (R * D) + N)
+          else
+                N
+        ).

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