[m-dev.] Re: Mercury Tcl/Tk interface broken
Fergus Henderson
fjh at cs.mu.OZ.AU
Fri Aug 27 03:47:49 AEST 1999
On 27-Aug-1999, Fergus Henderson <fjh at cs.mu.OZ.AU> wrote:
> On 26-Aug-1999, Zoltan Somogyi <zs at cs.mu.OZ.AU> wrote:
> > In April Fergus changed unique mode checking so that any unique variable that
> > is live on entry to any disjunction, even a model-det disjunction like this
> > one, will be set to mostly_unique.
> >
> > There are two changes we can make to fix this problem. First, Fergus should
> > change unique-mode checking again, so that what you check before making
> > a unique variable into only a mostly-unique variable is not the detism
> > of the disjunction, but the detism of the disjunct; you cannot backtrack
> > out of a det disjunct.
>
> That is a good suggestion. I'll do that.
I spoke a little too soon. For model_semi or model_det disjunctions,
Zoltan's suggestion is good. But it doesn't work for model_non disjunctions,
because the other disjuncts can be reached again when you backtrack to
find the second solution, even if the disjunction in question is model_det.
So I've adopted a hybrid solution.
----------
Estimated hours taken: 3
compiler/unique_modes.m:
Broaden the compiler's definition of unique-mode-correctness so that
the compiler now allows a few more cases than it previously did.
In particular, in model_det and model_semi disjunctions, only mark
the non-locals as mostly_unique rather than unique if the disjunct
can fail.
This fixes a problem where a previous bug-fix to unique modes
broke extras/graphics/mercury_tcltk/mtk.m.
Workspace: /home/mercury0/fjh/mercury
Index: compiler/unique_modes.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/unique_modes.m,v
retrieving revision 1.55
diff -u -r1.55 unique_modes.m
--- unique_modes.m 1999/07/14 07:15:30 1.55
+++ unique_modes.m 1999/08/26 17:42:29
@@ -277,20 +277,35 @@
mode_info_set_instmap(InstMap)
;
%
- % Mark all the variables which are nondet-live at the
+ % If the disjunction creates a choice point (i.e. is model_non),
+ % then mark all the variables which are live at the
% start of the disjunction and whose inst is `unique'
- % as instead being only `mostly_unique'.
+ % as instead being only `mostly_unique', since those variables
+ % may be needed again after we backtrack to that choice point
+ % and resume forward execution again.
%
+ % Note: for model_det or model_semi disjunctions,
+ % we may do some "shallow" backtracking from semidet
+ % disjuncts. But we handle that seperately for each
+ % disjunct, in unique_modes__check_disj.
+ %
{ goal_info_get_nonlocals(GoalInfo0, NonLocals) },
- mode_info_add_live_vars(NonLocals),
- make_all_nondet_live_vars_mostly_uniq,
- mode_info_remove_live_vars(NonLocals),
+ { goal_info_get_code_model(GoalInfo0, CodeModel) },
+ % does this disjunction create a choice point?
+ ( { CodeModel = model_non } ->
+ mode_info_add_live_vars(NonLocals),
+ make_all_nondet_live_vars_mostly_uniq,
+ mode_info_remove_live_vars(NonLocals)
+ ;
+ []
+ ),
%
% Now just modecheck each disjunct in turn, and then
% merge the resulting instmaps.
%
- unique_modes__check_disj(List0, List, InstMapList),
+ unique_modes__check_disj(List0, CodeModel, NonLocals,
+ List, InstMapList),
instmap__merge(NonLocals, InstMapList, disj)
),
mode_checkpoint(exit, "disj").
@@ -653,19 +668,45 @@
% the original instmap before processing the next one.
% Collect up a list of the resulting instmaps.
-:- pred unique_modes__check_disj(list(hlds_goal), list(hlds_goal),
- list(instmap), mode_info, mode_info).
-:- mode unique_modes__check_disj(in, out, out, mode_info_di, mode_info_uo)
- is det.
-
-unique_modes__check_disj([], [], []) --> [].
-unique_modes__check_disj([Goal0 | Goals0], [Goal | Goals],
- [InstMap | InstMaps]) -->
+:- pred unique_modes__check_disj(list(hlds_goal), code_model, set(prog_var),
+ list(hlds_goal), list(instmap), mode_info, mode_info).
+:- mode unique_modes__check_disj(in, in, in, out, out,
+ mode_info_di, mode_info_uo) is det.
+
+unique_modes__check_disj([], _, _, [], []) --> [].
+unique_modes__check_disj([Goal0 | Goals0], DisjCodeModel, DisjNonLocals,
+ [Goal | Goals], [InstMap | InstMaps]) -->
mode_info_dcg_get_instmap(InstMap0),
+ (
+ %
+ % If the disjunction was model_nondet, then we already marked
+ % all the non-locals as only being mostly-unique, so we
+ % don't need to do anything speical here...
+ %
+ { DisjCodeModel \= model_non },
+
+ %
+ % ... but for model_semi or model_det disjunctions, if the
+ % _disjunct_ can fail, then we still might backtrack to another
+ % disjunct, so again in that case we need to mark all the
+ % non-locals as being only mostly-unique rather than unique.
+ %
+ { Goal0 = _ - GoalInfo0 },
+ { goal_info_get_determinism(GoalInfo0, Determinism) },
+ { determinism_components(Determinism, CanFail, _) },
+ { CanFail = can_fail }
+ ->
+ mode_info_add_live_vars(DisjNonLocals),
+ make_all_nondet_live_vars_mostly_uniq,
+ mode_info_remove_live_vars(DisjNonLocals)
+ ;
+ []
+ ),
unique_modes__check_goal(Goal0, Goal),
mode_info_dcg_get_instmap(InstMap),
mode_info_set_instmap(InstMap0),
- unique_modes__check_disj(Goals0, Goals, InstMaps).
+ unique_modes__check_disj(Goals0, DisjCodeModel, DisjNonLocals,
+ Goals, InstMaps).
%-----------------------------------------------------------------------------%
--
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.
--------------------------------------------------------------------------
mercury-developers mailing list
Post messages to: mercury-developers at cs.mu.oz.au
Administrative Queries: owner-mercury-developers at cs.mu.oz.au
Subscriptions: mercury-developers-request at cs.mu.oz.au
--------------------------------------------------------------------------
More information about the developers
mailing list