[m-rev.] for review: adding promise ex declarations to the hlds with error checking
Lars Yencken
lljy at students.cs.mu.oz.au
Tue Feb 19 16:45:52 AEDT 2002
Hi Fergus,
Thanks for reviewing my diff. Here's the relative diff.
Lars
==============================================================
--- error_util.m
+++ error_util.m
@@ -421 +421 @@
- Piece = promise_to_string(PromiseType)
+ Piece = "`" ++ promise_to_string(PromiseType) ++ "' declaration"
--- goal_util.m
+++ goal_util.m
@@ -151,0 +152 @@
+ % returns all the predids that are used within a goal
@@ -154 +155,2 @@
-
+
+ % returns all the predids that are used in a list of goals
@@ -1300 +1302 @@
- Goals = [Goal|Rest],
+ Goals = [Goal | Rest],
@@ -1303 +1305 @@
- append(PredIds0, PredIds1, PredIds)
+ PredIds = PredIds0 ++ PredIds1
--- hlds_data.m
+++ hlds_data.m
@@ -1044,3 +1043,0 @@
-:- type exclusive_id == pred_id.
-:- type exclusive_ids == list(pred_id).
-
@@ -1048,2 +1045,2 @@
- % A table recording all promse_ex declarations (i.e. promise_exclusive,
- % promise_exhaustive and promise_exclusive_exhaustive).
+ % A table recording exclusivity declarations (i.e. promise_exclusive
+ % and promise_exclusive_exhaustive).
@@ -1060,2 +1057,10 @@
- % although whichever one succeeds may have multiple solutions.
-
+ % although whichever one succeeds may have multiple solutions. See
+ % notes/promise_ex.html for details of the declarations.
+ %
+
+ % an exclusive_id is the pred_id of an exclusivity declaration,
+ % and is useful in distinguishing between the arguments of the
+ % operations below on the exclusive_table
+:- type exclusive_id == pred_id.
+:- type exclusive_ids == list(pred_id).
+
@@ -1063,0 +1069 @@
+ % initialise the exclusive_table
@@ -1066,0 +1073,2 @@
+ % search the exclusive table and return the list of exclusivity
+ % declarations that use the predicate given by pred_id
@@ -1069,0 +1078,2 @@
+ % as for search, but aborts if no exclusivity declarations are
+ % found
@@ -1072,0 +1083 @@
+ % optimises the exclusive_table
@@ -1075,0 +1087,2 @@
+ % add to the exclusive table that pred_id is used in the
+ % exclusivity declaration exclusive_id
@@ -1084 +1097,3 @@
-:- type exclusive_table == map(pred_id, exclusive_ids).
+:- import_module multi_map.
+
+:- type exclusive_table == multi_map(pred_id, exclusive_id).
@@ -1086 +1101,2 @@
-exclusive_table_init(map__init).
+exclusive_table_init(ExclusiveTable) :-
+ multi_map__init(ExclusiveTable).
@@ -1089 +1105 @@
- map__lookup(ExclusiveTable, PredId, ExclusiveIds).
+ multi_map__lookup(ExclusiveTable, PredId, ExclusiveIds).
@@ -1092 +1108 @@
- map__search(ExclusiveTable, Id, ExclusiveIds).
+ multi_map__search(ExclusiveTable, Id, ExclusiveIds).
@@ -1095 +1111 @@
- map__optimize(ExclusiveTable0, ExclusiveTable).
+ multi_map__optimize(ExclusiveTable0, ExclusiveTable).
@@ -1099 +1115 @@
- map__search(ExclusiveTable0, PredId, ExclusiveIds)
+ multi_map__contains(ExclusiveTable0, PredId)
@@ -1101,2 +1117,2 @@
- map__det_update(ExclusiveTable0, PredId,
- [ExclusiveId|ExclusiveIds], ExclusiveTable)
+ multi_map__det_update(ExclusiveTable0, PredId, ExclusiveId,
+ ExclusiveTable)
@@ -1104 +1120 @@
- map__det_insert(ExclusiveTable0, PredId, [ExclusiveId],
+ multi_map__det_insert(ExclusiveTable0, PredId, ExclusiveId,
--- hlds_out.m
+++ hlds_out.m
@@ -373 +373,2 @@
- io__write_string(prog_out__promise_to_string(PromiseType))
+ io__write_string("`" ++ prog_out__promise_to_string(PromiseType)
+ ++ "' declaration")
@@ -417,0 +419 @@
+ io__write_string("`"),
@@ -419 +421 @@
- io__write_string(" declaration")
+ io__write_string("' declaration")
@@ -958 +960 @@
- io__write_string(":- promise all["),
+ io__write_string(":- promise all ["),
@@ -962 +964 @@
- io__write_string(":- all["),
+ io__write_string(":- all ["),
--- make_hlds.m
+++ make_hlds.m
@@ -805,7 +805,7 @@
- %
- % If the outermost existentially quantified variables
- % are placed in the head of the assertion, the
- % typechecker will avoid warning about unbound
- % type variables as this implicity adds a universal
- % quantification of the typevariables needed.
- %
+ %
+ % If the outermost universally quantified variables
+ % are placed in the head of the dummy predicate, the
+ % typechecker will avoid warning about unbound
+ % type variables as this implicity adds a universal
+ % quantification of the typevariables needed.
+ %
@@ -813 +813,3 @@
- ( { \+ PromiseType = true } ->
+
+ % extra error checking for promise ex declarations
+ ( { PromiseType \= true } ->
@@ -817,0 +820,2 @@
+
+ % add as dummy predicate
@@ -8427,2 +8431 @@
-% XXX promise_ex declarations
-%
+% promise ex error checking
@@ -8429,0 +8433,9 @@
+% The following predicates are used to perform extra error checking specific
+% to promise ex declarations (see notes/promise_ex.html). Currently, the
+% following checks are performed:
+% * check for universally quantified variables
+% * check if universal quantification is placed in the wrong
+% position (i.e. after the `promise_exclusive' rather than
+% before it)
+% * check that its goal is a disjunction and that each arm of the
+% disjunction has at most one call, and otherwise has only unifications
@@ -8431,12 +8443 @@
-:- type promise_ex_goal
- ---> ok(goals)
- ; error(string, prog_context).
-
- % Perform error checking for a promise ex declaration.
- % The following checks are done:
- % * check for universally quantified variables
- % * check if universal quantification is placed in the wrong
- % position (i.e. after the `promise_exclusive' rather than
- % before it)
- % * check that each arm of the disjunction has at most one call,
- % but otherwise has only unifications
+ % perform above checks on a promise ex declaration
@@ -8452 +8453 @@
- { UnivVars = [_|_] }
+ { UnivVars = [_ | _] }
@@ -8456,2 +8457,3 @@
-
- % strip off any existential quantification, then
+ % check for misplaced universal quantification, otherwise find the
+ % disjunction, flatten it out into list form and perform further
+ % checks
@@ -8465,2 +8467,2 @@
- { list__map(flatten_to_cons_list, DisjList, DisjConsList) },
- check_list_cons_list(PromiseType, DisjConsList)
+ { list__map(flatten_to_conj_list, DisjList, DisjConsList) },
+ check_disjunction(PromiseType, DisjConsList)
@@ -8474 +8476,2 @@
-
+ % turns the goal of a promise ex declaration into a list of goals,
+ % where each goal is an arm of the disjunction
@@ -8481 +8484 @@
- append(GoalListA, GoalListB, GoalList)
+ GoalList = GoalListA ++ GoalListB
@@ -8486,3 +8489,5 @@
-:- pred flatten_to_cons_list(goal, goals).
-:- mode flatten_to_cons_list(in, out) is det.
-flatten_to_cons_list(GoalExpr - Context, GoalList) :-
+ % takes a goal representing an arm of a disjunction and turn it into
+ % a list of conjunct goals
+:- pred flatten_to_conj_list(goal, goals).
+:- mode flatten_to_conj_list(in, out) is det.
+flatten_to_conj_list(GoalExpr - Context, GoalList) :-
@@ -8490,3 +8495,3 @@
- flatten_to_cons_list(GoalA, GoalListA),
- flatten_to_cons_list(GoalB, GoalListB),
- append(GoalListA, GoalListB, GoalList)
+ flatten_to_conj_list(GoalA, GoalListA),
+ flatten_to_conj_list(GoalB, GoalListB),
+ GoalList = GoalListA ++ GoalListB
@@ -8497,3 +8502,5 @@
-:- 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) -->
+ % taking a list of arms of the disjunction, check each arm
+ % individually
+:- pred check_disjunction(promise_type, list(goals), io__state, io__state).
+:- mode check_disjunction(in, in, di, uo) is det.
+check_disjunction(PromiseType, DisjConsList) -->
@@ -8503,3 +8510,3 @@
- { DisjConsList = [ConsList|Rest] },
- check_cons_list(PromiseType, ConsList, no),
- check_list_cons_list(PromiseType, Rest)
+ { DisjConsList = [ConsList | Rest] },
+ check_disj_arm(PromiseType, ConsList, no),
+ check_disjunction(PromiseType, Rest)
@@ -8508,19 +8515,5 @@
-:- pred check_disj_goals(promise_type, list(goals), io__state, io__state).
-:- mode check_disj_goals(in, in, di, uo) is det.
-check_disj_goals(PromiseType, GoalList0) -->
- (
- { GoalList0 = [] }
- ;
- { GoalList0 = [Goal0|GoalList] },
- check_cons_list(PromiseType, Goal0, no),
- check_disj_goals(PromiseType, GoalList)
- ).
-
-
- % 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) -->
+ % only one goal in an arm is allowed to be a call, the rest must be
+ % unifications
+:- pred check_disj_arm(promise_type, goals, bool, io__state, io__state).
+:- mode check_disj_arm(in, in, in, di, uo) is det.
+check_disj_arm(PromiseType, Goals, CallUsed) -->
@@ -8530 +8523 @@
- { Goals = [GoalExpr - Context|Rest] },
+ { Goals = [GoalExpr - Context | Rest] },
@@ -8532 +8525 @@
- check_cons_list(PromiseType, Rest, CallUsed)
+ check_disj_arm(PromiseType, Rest, CallUsed)
@@ -8534 +8527 @@
- check_cons_list(PromiseType, [Goal|Rest], CallUsed)
+ check_disj_arm(PromiseType, [Goal | Rest], CallUsed)
@@ -8542 +8535 @@
- check_cons_list(PromiseType, Rest, yes)
+ check_disj_arm(PromiseType, Rest, yes)
@@ -8545 +8538 @@
- check_cons_list(PromiseType, Rest, CallUsed)
+ check_disj_arm(PromiseType, Rest, CallUsed)
@@ -8550 +8543 @@
- % called for any promise_ex_error
+ % called for any error in the above checks
@@ -8555,8 +8548,8 @@
- 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.
+ { ErrorPieces = [
+ words("In"),
+ fixed("`" ++ prog_out__promise_to_string(PromiseType) ++ "' declaration:"),
+ nl,
+ words("error:"),
+ words(Message)
+ ] },
+ error_util__write_error_pieces(Context, 0, ErrorPieces).
--- post_typecheck.m
+++ post_typecheck.m
@@ -731,3 +731,4 @@
- (
- % case for assertions
- PromiseType = true,
+ (
+ % case for assertions
+ PromiseType = true
+ ->
@@ -743,11 +744,7 @@
- % case for exclusivity
- PromiseType = exclusive,
- 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 exclusivity
- PromiseType = exclusive_exhaustive,
+ % case for exclusivity
+ (
+ PromiseType = exclusive
+ ;
+ PromiseType = exclusive_exhaustive
+ )
+ ->
@@ -759,0 +757 @@
+
@@ -761,2 +759 @@
- % case for exhaustiveness -- not yet implemented
- PromiseType = exhaustive,
+ % case for exhaustiveness -- XXX not yet implemented
@@ -766,0 +764 @@
+ % get the goal from a promise_ex declaration
--------------------------------------------------------------------------
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