[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