mirror of
https://github.com/Mercury-Language/mercury.git
synced 2025-12-14 13:23:53 +00:00
Prepare for an extension of promise_equivalent_solutions that will allow us
Estimated hours taken: 5 Branches: main Prepare for an extension of promise_equivalent_solutions that will allow us to better handle values of user-defined types. The problem is that currently, the deconstruction of a value of such a type can be followed only by code that cannot fail, otherwise the cc_multi deconstruction is not in the required single-solution context. If the following code is naturally semidet, this can be worked around by turning it into det code returning a maybe and testing the maybe outside the promise_equivalent_solutions, but this is inefficient, and in any case it does not generalize to nondet code without even more horrendous inefficiency and inconvenience. (You have to create a nondet closure and call it outside the promise_equivalent_solutions.) The solution I came up with is something is to have a construct that contains - a list of deconstructions on types with user-defined equality, - a goal, and - the list of outputs of that goal. The idea is that this would be transformed into a conjunction of the first and second items, and wrapped inside a special kind of conj that provides a scope for the implicit promise, which is that the set of solutions of the goal in the second item doesn't depend on what concrete terms the deconstructions in the first item return out of the set of concrete terms they *could* return. The deconstructions in the first item would be marked to tell determinism analysis to effectively ignore the fact that they involve user-defined equality. The actual addition of that construct is left for a future change, after we agree on the syntax. compiler/hlds_goal.m: Generalize the existing promise_equivalent_solutions scope to a promise_solutions scope with a flag that says whether in the source code it was originally the existing "promise_equivalent_solutions" construct or the new construct (which doesn't exist yet, but is indicated by the symbol "same_solutions" for now). Replace the conj and par_conj hlds_goal_exprs with a single goal expression: conj with an additional argument which is either plain_conj or parallel_conj. This was part of an earlier design in which a third kind of disjunction took the role now assigned to the new kind of promise_solutions scope, but turned out to be a good idea anyway, since in many places the compiler does treat the two kinds of conjunctions the same. This part of the change is responsible for the fact that this change results in a net *reduction* of about 40 lines. Move the most frequently used kinds of goal expressions to the front of the type declaration to allow the compiler to make better decisions about tag allocation. Add the goal marker we will add to the deconstructions in the first item. Replace the true_goal and fail_goal predicates with functions to make them easier to use, and rename their variants that take a context argument to avoid unnecessary ambiguity. compiler/*.m: Conform to the change in hlds_goal.m. Misc changes to make code more robust, e.g. replacing semidet predicates on goal expressions with functions returning bool. Misc cleanups, e.g. removal of unnecessary module qualifications that made lines too long, renaming predicates whose names include "disj" if they are also used to process parallel conjunctions (since in both parallel conjunctions and in disjunctions the goals are independent), and turning semidet predicates that switch on goal expressions into bool functions (to make similar changes more rebust in the future).
This commit is contained in:
@@ -270,9 +270,7 @@ goal_may_alloc_temp_frame_2(scope(_, Goal), May) :-
|
||||
).
|
||||
goal_may_alloc_temp_frame_2(not(Goal), May) :-
|
||||
goal_may_alloc_temp_frame(Goal, May).
|
||||
goal_may_alloc_temp_frame_2(conj(Goals), May) :-
|
||||
goal_list_may_alloc_temp_frame(Goals, May).
|
||||
goal_may_alloc_temp_frame_2(par_conj(Goals), May) :-
|
||||
goal_may_alloc_temp_frame_2(conj(_ConjType, Goals), May) :-
|
||||
goal_list_may_alloc_temp_frame(Goals, May).
|
||||
goal_may_alloc_temp_frame_2(disj(Goals), May) :-
|
||||
goal_list_may_alloc_temp_frame(Goals, May).
|
||||
|
||||
Reference in New Issue
Block a user