[m-rev.] for review: adding promise ex declarations to the hlds with error checking
Fergus Henderson
fjh at cs.mu.OZ.AU
Mon Feb 18 17:22:28 AEDT 2002
On 15-Feb-2002, Lars Yencken <lljy at students.cs.mu.oz.au> wrote:
> +++ goal_util.m 14 Feb 2002 01:26:01 -0000
> @@ -149,6 +149,12 @@
> :- pred direct_subgoal(hlds_goal_expr, hlds_goal).
> :- mode direct_subgoal(in, out) is nondet.
>
> +:- pred predids_from_goal(hlds_goal, list(pred_id)).
> +:- mode predids_from_goal(in, out) is det.
> +
> +:- pred predids_from_goals(list(hlds_goal), list(pred_id)).
> +:- mode predids_from_goals(in, out) is det.
These need to be documented.
Our Mercury coding guidelines say that all procedures which
are exported from a module should be documented.
> +predids_from_goals(Goals, PredIds) :-
> + (
> + Goals = [],
> + PredIds = []
> + ;
> + Goals = [Goal|Rest],
> + predids_from_goal(Goal, PredIds0),
> + predids_from_goals(Rest, PredIds1),
> + append(PredIds0, PredIds1, PredIds)
> + ).
It's a little clearer to use the infix `++' function.
> Index: hlds_data.m
> +++ hlds_data.m 14 Feb 2002 01:22:19 -0000
> @@ -1038,3 +1038,70 @@
>
> %-----------------------------------------------------------------------------%
> %-----------------------------------------------------------------------------%
> +
> +:- interface.
There should be a comment at the start explaining what this part
of the module is about.
> +:- type exclusive_id == pred_id.
> +:- type exclusive_ids == list(pred_id).
There should be a comment explaining what an exclusive_id represents.
> + %
> + % A table recording all promse_ex declarations (i.e. promise_exclusive,
> + % promise_exhaustive and promise_exclusive_exhaustive).
> + %
> + % e.g. :- all [X]
> + % promise_exclusive
> + % some [Y] (
> + % p(X, Y)
> + % ;
> + % q(X)
> + % ).
> + %
> + % promises that only one of p(X, Y) and q(X) can succeed at a time,
> + % although whichever one succeeds may have multiple solutions.
The documentation about what a promise_ex declaration is would be
better placed at the start of this section.
There should also be a pointer to compiler/notes/promise_ex.html.
> +:- type exclusive_table.
> +
> +:- pred exclusive_table_init(exclusive_table).
> +:- mode exclusive_table_init(out) is det.
> +
> +:- pred exclusive_table_search(exclusive_table, pred_id, exclusive_ids).
> +:- mode exclusive_table_search(in, in, out) is semidet.
> +
> +:- pred exclusive_table_lookup(exclusive_table, pred_id, exclusive_ids).
> +:- mode exclusive_table_lookup(in, in, out) is det.
> +
> +:- pred exclusive_table_optimize(exclusive_table, exclusive_table).
> +:- mode exclusive_table_optimize(in, out) is det.
> +
> +:- pred exclusive_table_add(pred_id, exclusive_id, exclusive_table,
> + exclusive_table).
> +:- mode exclusive_table_add(in, in, in, out) is det.
These procedures should be documented.
> +%-----------------------------------------------------------------------------%
> +
> +:- implementation.
> +
> +:- type exclusive_table == map(pred_id, exclusive_ids).
> +
> +exclusive_table_init(map__init).
> +
> +exclusive_table_lookup(ExclusiveTable, PredId, ExclusiveIds) :-
> + map__lookup(ExclusiveTable, PredId, ExclusiveIds).
> +
> +exclusive_table_search(ExclusiveTable, Id, ExclusiveIds) :-
> + map__search(ExclusiveTable, Id, ExclusiveIds).
> +
> +exclusive_table_optimize(ExclusiveTable0, ExclusiveTable) :-
> + map__optimize(ExclusiveTable0, ExclusiveTable).
> +
> +exclusive_table_add(ExclusiveId, PredId, ExclusiveTable0, ExclusiveTable) :-
> + (
> + map__search(ExclusiveTable0, PredId, ExclusiveIds)
> + ->
> + map__det_update(ExclusiveTable0, PredId,
> + [ExclusiveId|ExclusiveIds], ExclusiveTable)
> + ;
> + map__det_insert(ExclusiveTable0, PredId, [ExclusiveId],
> + ExclusiveTable)
> + ).
Is there any particular reason why you didn't use
`multi_map' rather than `map'?
> Index: hlds_out.m
...
> + % print initial formatting differently for assertions
> + ( { PromiseType = true } ->
> + io__write_string(":- promise all["),
> + io__write_list(HeadVars, ", ", PrintVar),
> + io__write_string("] (\n")
> + ;
> + io__write_string(":- all["),
> + io__write_list(HeadVars, ", ", PrintVar),
> + io__write_string("]"),
> + mercury_output_newline(Indent),
> + prog_out__write_promise_type(PromiseType),
> + io__nl
> + ),
You should output "all [" rather than "all[" (in both places).
Also it looks like the output for promise_ex declarations
is missing a `('.
> @@ -801,8 +802,6 @@
>
> add_item_clause(promise(PromiseType, Goal, VarSet, UnivVars),
> Status, Status, Context, Module0, Module, Info0, Info) -->
> - ( { PromiseType = true } -> % promise is an assertion
> -
> %
> % If the outermost existentially quantified variables
> % are placed in the head of the assertion, the
You should fix up the indentation of this clause.
> @@ -810,34 +809,43 @@
> % type variables as this implicity adds a universal
> % quantification of the typevariables needed.
> %
> - { term__var_list_to_term_list(UnivVars, HeadVars) },
> + { term__var_list_to_term_list(UnivVars, HeadVars) },
> + ( { \+ PromiseType = true } ->
Write that as `( { PromiseType \= true } ->'
> @@ -8413,4 +8421,144 @@
...
> +%
> +% XXX promise_ex declarations
> +%
> +%
> +
> +:- type promise_ex_goal
> + ---> ok(goals)
> + ; error(string, prog_context).
The XXX comment here should be replaced with a comment
that explains what the `promise_ex_goal' type represents
and how it is used (perhaps with a pointer to compiler/notes/promise_ex.html).
> + % strip off any existential quantification, then
> +:- pred check_promise_ex_goal(promise_type, goal, io__state, io__state).
That comment is unfinished.
> +:- pred flatten_to_cons_list(goal, goals).
> +:- mode flatten_to_cons_list(in, out) is det.
> +flatten_to_cons_list(GoalExpr - Context, GoalList) :-
> + ( GoalExpr = ( GoalA , GoalB ) ->
> + flatten_to_cons_list(GoalA, GoalListA),
> + flatten_to_cons_list(GoalB, GoalListB),
> + append(GoalListA, GoalListB, GoalList)
> + ;
> + GoalList = [GoalExpr - Context]
> + ).
What is "cons_list" supposed to mean here?
I think you need s/cons_list/conj_list/g
Also a brief comment saying what the predicate is supposed to do
would help.
> +:- pred check_list_cons_list(promise_type, list(goals), io__state, io__state).
> +:- mode check_list_cons_list(in, in, di, uo) is det.
> +check_list_cons_list(PromiseType, DisjConsList) -->
> + (
> + { DisjConsList = [] }
> + ;
> + { DisjConsList = [ConsList|Rest] },
> + check_cons_list(PromiseType, ConsList, no),
> + check_list_cons_list(PromiseType, Rest)
> + ).
Likewise here.
> + % check a cons list of goals in a disj, ensuring that they are all
> + % either unifications or calls
> + % only one call is allowed per cons list, as each cons list represents
> + % one arm of the disjunction
> +:- pred check_cons_list(promise_type, goals, bool, io__state, io__state).
> +:- mode check_cons_list(in, in, in, di, uo) is det.
> +check_cons_list(PromiseType, Goals, CallUsed) -->
Likewise here too.
> + (
> + { Goals = [] }
> + ;
> + { Goals = [GoalExpr - Context|Rest] },
s/|/ | /
> + % called for any promise_ex_error
> +:- pred promise_ex_error(promise_type, prog_context, string,
> + io__state, io__state).
> +:- mode promise_ex_error(in, in, in, di, uo) is det.
> +promise_ex_error(PromiseType, Context, Message) -->
> + io__set_exit_status(1),
> + prog_out__write_context(Context),
> + io__write_string("In " ++
> + prog_out__promise_to_string(PromiseType) ++ " declaration:\n"),
> + prog_out__write_context(Context),
> + io__write_string(" error: "),
> + io__write_string(Message),
> + io__nl.
You should provide more explanations for each of the error messages,
and output them if the verbose_errors option is set.
There should be single quotes around the declaration type,
i.e. output
In `promise_exclusive' declaration:
rather than
In promise_exclusive declaration:
Also the error messages should ideally be output with write_error_pieces
from error_util.m.
> Index: post_typecheck.m
...
> + % store promise declaration, normalise goal and return new
> + % module_info and the goal for further processing
> +:- pred store_promise(promise_type, module_info, pred_id, module_info,
> + hlds_goal).
> +:- mode store_promise(in, in, in, out, out) is det.
> +store_promise(PromiseType, Module0, PromiseId, Module, Goal) :-
> (
...
> + ;
> + % case for exclusivity
> + PromiseType = exclusive_exhaustive,
The comment there doesn't match the code.
> + promise_ex_goal(PromiseId, Module0, Goal),
> + predids_from_goal(Goal, PredIds),
> + module_info_exclusive_table(Module0, Table0),
> + list__foldl(exclusive_table_add(PromiseId), PredIds, Table0,
> + Table),
> + module_info_set_exclusive_table(Module0, Table, Module)
> + ;
> + % case for exhaustiveness -- not yet implemented
> + PromiseType = exhaustive,
> + promise_ex_goal(PromiseId, Module0, Goal),
> + Module0 = Module
> + ).
Add "XXX" before "not yet implemented".
Otherwise that looks good. Please post both a full and a relative diff
when you've addressed these changes.
--
Fergus Henderson <fjh at cs.mu.oz.au> | "I have always known that the pursuit
The University of Melbourne | of excellence is a lethal habit"
WWW: <http://www.cs.mu.oz.au/~fjh> | -- the last words of T. S. Garp.
--------------------------------------------------------------------------
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