diff: impurity bug fixes
Fergus Henderson
fjh at cs.mu.OZ.AU
Wed Oct 21 01:03:54 AEST 1998
I'll commit this now, but of course anyone who wants should
feel free to review it.
Estimated hours taken: 1.5
Fix a couple of bugs related to pruning of impure goals with no output
variables.
compiler/det_analysis.m:
Fix a bug: the compiler was automatically inserting pruning
across impure goals with no output variables. That should
happen only for pure or semipure goals. To prevent pruning
in those cases, I changed it so that impure goals with no
output variables are not considered single-solution contexts.
doc/reference_manual.texi:
Document the above-mentioned change.
compiler/clause_to_proc.m:
Fix a bug: when converting a bunch of clauses into a disjunction,
clause_to_proc.m was not computing the proper purity annotation
on the goal_info for the disjunction.
tests/hard_coded/Mmakefile:
tests/hard_coded/impure_prune.m:
tests/hard_coded/impure_prune.exp:
A test case for the above-mentioned changes to det_analysis.m
and clause_to_proc.m.
Index: compiler/clause_to_proc.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/clause_to_proc.m,v
retrieving revision 1.22
diff -u -r1.22 clause_to_proc.m
--- clause_to_proc.m 1998/08/04 14:56:06 1.22
+++ clause_to_proc.m 1998/10/20 14:56:40
@@ -50,7 +50,7 @@
:- implementation.
-:- import_module hlds_goal, hlds_data, prog_data, mode_util, make_hlds.
+:- import_module hlds_goal, hlds_data, prog_data, mode_util, make_hlds, purity.
:- import_module globals.
:- import_module int, set, map.
@@ -141,11 +141,16 @@
( GoalList = [SingleGoal] ->
Goal = SingleGoal
;
- % Construct a goal_info for the disjunction.
+ %
+ % Convert the list of clauses into a disjunction,
+ % and construct a goal_info for the disjunction.
+ %
+
+ %
% We use the context of the first clause, unless
% there weren't any clauses at all, in which case
% we use the context of the mode declaration.
- % The non-local vars are just the head variables.
+ %
goal_info_init(GoalInfo0),
( GoalList = [FirstGoal | _] ->
FirstGoal = _ - FirstGoalInfo,
@@ -154,12 +159,39 @@
proc_info_context(Proc0, Context)
),
goal_info_set_context(GoalInfo0, Context, GoalInfo1),
+
+ %
+ % The non-local vars are just the head variables.
+ %
set__list_to_set(HeadVars, NonLocalVars),
- goal_info_set_nonlocals(GoalInfo1, NonLocalVars, GoalInfo),
+ goal_info_set_nonlocals(GoalInfo1, NonLocalVars, GoalInfo2),
+
+ %
+ % The disjunction is impure/semipure if any of the disjuncts
+ % is impure/semipure.
+ %
+ (
+ list__member(_SubGoal - SubGoalInfo, GoalList),
+ \+ goal_info_is_pure(SubGoalInfo)
+ ->
+ list__map(get_purity, GoalList, PurityList),
+ list__foldl(worst_purity, PurityList, (pure), Purity),
+ add_goal_info_purity_feature(GoalInfo2, Purity,
+ GoalInfo)
+ ;
+ GoalInfo2 = GoalInfo
+ ),
+
map__init(Empty),
Goal = disj(GoalList, Empty) - GoalInfo
),
proc_info_set_body(Proc0, VarSet, VarTypes, HeadVars, Goal, Proc).
+
+:- pred get_purity(hlds_goal, purity).
+:- mode get_purity(in, out) is det.
+
+get_purity(_Goal - GoalInfo, Purity) :-
+ infer_goal_info_purity(GoalInfo, Purity).
:- pred select_matching_clauses(list(clause), proc_id, list(clause)).
:- mode select_matching_clauses(in, in, out) is det.
Index: compiler/det_analysis.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/det_analysis.m,v
retrieving revision 1.135
diff -u -r1.135 det_analysis.m
--- det_analysis.m 1998/09/10 06:38:21 1.135
+++ det_analysis.m 1998/10/20 14:25:56
@@ -119,7 +119,7 @@
:- implementation.
-:- import_module prog_data, det_report.
+:- import_module prog_data, det_report, purity.
:- import_module type_util, modecheck_call, mode_util, options, passes_aux.
:- import_module hlds_out, mercury_to_mercury.
:- import_module assoc_list, bool, map, set, require, term.
@@ -294,10 +294,14 @@
goal_info_get_nonlocals(GoalInfo0, NonLocalVars),
goal_info_get_instmap_delta(GoalInfo0, DeltaInstMap),
- % If a goal has no output variables, then the goal is in
- % single-solution context
+ % If a pure or semipure goal has no output variables,
+ % then the goal is in single-solution context
- ( det_no_output_vars(NonLocalVars, InstMap0, DeltaInstMap, DetInfo) ->
+ (
+ det_no_output_vars(NonLocalVars, InstMap0, DeltaInstMap,
+ DetInfo),
+ \+ goal_info_is_impure(GoalInfo0)
+ ->
OutputVars = no,
SolnContext = first_soln
;
Index: doc/reference_manual.texi
===================================================================
RCS file: /home/mercury1/repository/mercury/doc/reference_manual.texi,v
retrieving revision 1.105
diff -u -r1.105 reference_manual.texi
--- reference_manual.texi 1998/09/28 06:26:54 1.105
+++ reference_manual.texi 1998/10/20 14:08:37
@@ -1646,7 +1646,8 @@
and the maximum number of solutions of the goal (0, 1, or more).
If the inference process below reports that a goal can succeed more than once,
but the goal generates no outputs that are visible from outside the goal,
-the final determinism of the goal
+and the goal is not impure (@pxref{Impurity}),
+then the final determinism of the goal
will be based on the goal succeeding at most once,
since the compiler will implicitly prune away any duplicate solutions.
Index: tests/hard_coded/Mmakefile
===================================================================
RCS file: /home/mercury1/repository/tests/hard_coded/Mmakefile,v
retrieving revision 1.43
diff -u -r1.43 Mmakefile
--- Mmakefile 1998/10/01 07:41:24 1.43
+++ Mmakefile 1998/10/20 14:23:12
@@ -51,6 +51,7 @@
ho_solns \
ho_univ_to_type \
impossible_unify \
+ impure_prune \
integer_test \
merge_and_remove_dups \
minint_bug \
Index: tests/hard_coded/impure_prune.exp
===================================================================
RCS file: impure_prune.exp
diff -N impure_prune.exp
--- /dev/null Wed Oct 21 00:13:20 1998
+++ impure_prune.exp Wed Oct 21 00:58:15 1998
@@ -0,0 +1 @@
+X = 3
Index: tests/hard_coded/impure_prune.m
===================================================================
RCS file: impure_prune.m
diff -N impure_prune.m
--- /dev/null Wed Oct 21 00:13:20 1998
+++ impure_prune.m Wed Oct 21 00:21:10 1998
@@ -0,0 +1,40 @@
+:- module impure_prune.
+:- interface.
+:- import_module io.
+
+:- pred main(state::di, state::uo) is det.
+
+:- implementation.
+:- import_module int, require.
+
+:- pragma promise_pure(main/2).
+
+main -->
+ ( { impure do_impure_stuff, fail } ->
+ { error("not reached") }
+ ;
+ { semipure get_counter(X) },
+ print("X = "), print(X), nl
+ ).
+
+:- impure pred do_impure_stuff is multi.
+do_impure_stuff :-
+ impure bump_counter.
+do_impure_stuff :-
+ impure bump_counter.
+do_impure_stuff :-
+ impure bump_counter.
+
+:- impure pred bump_counter is det.
+bump_counter :-
+ semipure get_counter(X),
+ impure set_counter(X + 1).
+
+:- semipure pred get_counter(int::out) is det.
+:- impure pred set_counter(int::in) is det.
+
+:- pragma c_header_code("extern Integer counter;").
+:- pragma c_code("Integer counter = 0;").
+:- pragma c_code(get_counter(X::out), will_not_call_mercury, "X = counter;").
+:- pragma c_code(set_counter(X::in), will_not_call_mercury, "counter = X;").
+
--
Fergus Henderson <fjh at cs.mu.oz.au> | "I have always known that the pursuit
WWW: <http://www.cs.mu.oz.au/~fjh> | of excellence is a lethal habit"
PGP: finger fjh at 128.250.37.3 | -- the last words of T. S. Garp.
More information about the developers
mailing list