[m-rev.] diff: Make the recursion patterns analysis more robust.
Paul Bone
pbone at csse.unimelb.edu.au
Fri Oct 8 23:49:29 AEDT 2010
Make the recursion patterns analysis more robust.
Handle semidet and committed choice disjunctions in the recursion patterns
analysis.
deep_profiler/recursion_patterns.m:
As above.
deep_profiler/measurement_units.m:
Add a new function, not_probability that returns the probability that a
certain probability will not occur.
Index: deep_profiler/measurement_units.m
===================================================================
RCS file: /home/mercury1/repository/mercury/deep_profiler/measurement_units.m,v
retrieving revision 1.7
diff -u -p -b -r1.7 measurement_units.m
--- deep_profiler/measurement_units.m 26 Aug 2010 06:29:27 -0000 1.7
+++ deep_profiler/measurement_units.m 8 Oct 2010 12:46:26 -0000
@@ -137,6 +137,9 @@
:- func or(probability, probability) = probability.
:- func and(probability, probability) = probability.
+ % The probability of the given probability not occuring.
+:- func not_probability(probability) = probability.
+
%-----------------------------------------------------------------------------%
%
% Code for formatting numbers.
@@ -306,6 +309,8 @@ or(A, B) = A + B.
% Combine conjoint probabilities with multiplication.
and(A, B) = A * B.
+not_probability(X) = 1.0 - X.
+
%-----------------------------------------------------------------------------%
%
% Code for formatting numbers.
Index: deep_profiler/recursion_patterns.m
===================================================================
RCS file: /home/mercury1/repository/mercury/deep_profiler/recursion_patterns.m,v
retrieving revision 1.5
diff -u -p -b -r1.5 recursion_patterns.m
--- deep_profiler/recursion_patterns.m 7 Oct 2010 02:38:10 -0000 1.5
+++ deep_profiler/recursion_patterns.m 8 Oct 2010 12:46:26 -0000
@@ -276,8 +276,7 @@ single_rec_average_recursion_cost(BaseCo
).
:- type recursion_error
- ---> re_unhandled_determinism(detism_rep)
- ; re_unhandled_disjunction.
+ ---> re_unhandled_determinism(detism_rep).
% goal_recursion_data(RecursiveCallees, Goal, GoalPath,
% init_recursion_data, RecursionData)
@@ -306,8 +305,8 @@ goal_recursion_data(ThisClique, CallSite
Conjs, !:RecursionData)
;
GoalExpr = disj_rep(Disjs),
- disj_recursion_data(ThisClique, CallSiteMap, GoalPath, 1, Disjs,
- !:RecursionData)
+ disj_recursion_data(ThisClique, CallSiteMap, GoalPath, 1, certain,
+ Disjs, !:RecursionData)
;
GoalExpr = switch_rep(_, _, Cases),
switch_recursion_data(ThisClique, CallSiteMap, GoalPath, 1, Cases,
@@ -370,18 +369,8 @@ conj_recursion_data(ThisClique, CallSite
RecursionData = proc_dead_code
;
ConjRecursionData = recursion_data(_, _, _),
- (
- get_coverage_before_and_after(Conj ^ goal_annotation, Before, After)
- ->
- ( After > Before ->
- % Nondet code can overflow this probability.
- ConjSuccessProb = certain
- ;
- ConjSuccessProb = probable(float(After) / float(Before))
- )
- ;
- error(this_file ++ "expected complete coverage information")
- ),
+ success_probability_from_coverage(Conj ^ goal_annotation,
+ ConjSuccessProb),
SuccessProb = and(SuccessProb0, ConjSuccessProb),
conj_recursion_data(ThisClique, CallSiteMap, GoalPath, ConjNum + 1,
SuccessProb, Conjs, ConjsRecursionData),
@@ -391,11 +380,52 @@ conj_recursion_data(ThisClique, CallSite
:- pred disj_recursion_data(clique_ptr::in,
map(goal_path, cost_and_callees)::in, goal_path::in, int::in,
- list(goal_rep(coverage_info))::in, recursion_data::out) is det.
+ probability::in, list(goal_rep(coverage_info))::in, recursion_data::out)
+ is det.
+
+disj_recursion_data(_, _, _, _, _, [], simple_recursion_data(0.0, 0)).
+disj_recursion_data(ThisClique, CallSiteMap, GoalPath, DisjNum, FailureProb0,
+ [Disj | Disjs], RecursionData) :-
+ % Handle only semidet and committed-choice disjunctions, once a goal
+ % succeeds it cannot be re-entered.
+ goal_recursion_data(ThisClique, CallSiteMap,
+ goal_path_add_at_end(GoalPath, step_disj(DisjNum)), Disj,
+ DisjRecursionData),
+ (
+ DisjRecursionData = proc_dead_code,
+ % If the first disjunct was never tried then no other disjuncts will
+ % ever be tried.
+ RecursionData = proc_dead_code
+ ;
+ DisjRecursionData = recursion_data(_, _, _),
+ % Handle this just like a semidet conjunction, except that we go to the
+ % next disjunct if it _fails_.
+ success_probability_from_coverage(Disj ^ goal_annotation,
+ ConjSuccessProb),
+ ConjFailureProb = not_probability(ConjSuccessProb),
+ FailureProb = and(FailureProb0, ConjFailureProb),
+ disj_recursion_data(ThisClique, CallSiteMap, GoalPath, DisjNum + 1,
+ FailureProb, Disjs, DisjsRecursionData),
+ merge_recursion_data_sequence(DisjRecursionData, DisjsRecursionData,
+ RecursionData)
+ ).
-disj_recursion_data(_, _, _, _, _, !:RecursionData) :-
- !:RecursionData = simple_recursion_data(0.0, 0),
- recursion_data_add_error(re_unhandled_disjunction, !RecursionData).
+:- pred success_probability_from_coverage(coverage_info::in, probability::out)
+ is det.
+
+success_probability_from_coverage(Coverage, SuccessProb) :-
+ (
+ get_coverage_before_and_after(Coverage, Before, After)
+ ->
+ ( After > Before ->
+ % Nondet code can overflow this probability.
+ SuccessProb = certain
+ ;
+ SuccessProb = probable(float(After) / float(Before))
+ )
+ ;
+ error(this_file ++ "expected complete coverage information")
+ ).
:- pred ite_recursion_data(clique_ptr::in,
map(goal_path, cost_and_callees)::in, goal_path::in,
@@ -700,8 +730,6 @@ simple_recursion_data(Cost, Calls) =
error_to_string(re_unhandled_determinism(Detism)) =
format("%s code is not handled", [s(string(Detism))]).
-error_to_string(re_unhandled_disjunction) =
- "Disjunctions are not currently handled".
%----------------------------------------------------------------------------%
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 490 bytes
Desc: Digital signature
URL: <http://lists.mercurylang.org/archives/reviews/attachments/20101008/dddb33bc/attachment.sig>
More information about the reviews
mailing list