mirror of
https://github.com/Mercury-Language/mercury.git
synced 2026-04-22 04:43:53 +00:00
Estimated hours taken: 10 Branches: main, release Fix the monitors that were computing coverage rates in Morphine. The problem was the following. In order to check that two successes and one failure occur for a multi predicate, I was looking at two exits and one fail; but this is wrong since, of course, the two exits can be produced by different calls, and since all multi predicates ends up with a fail event. To get it right, I need to associate the call number to exit and fail events. To do that, I maintain at exit ports the list of call numbers; when an exit event occurs, I consider it as covered iff the current call number is in the list. On the contrary, I consider a failure as covered at a fail port iff the current call number is not in the list. This also holds for semidet and nondet procedures. extras/morphine/non-regression-tests/queens.exp: Update the new expected outputs. extras/morphine/non-regression-tests/queens.in: Update the year of the copyrigth message. extras/morphine/source/call_site_cov.in: extras/morphine/source/pred_cov.in: Change the code so that it does what it is supposed to do. Also use a map instead of a list to store what has to be covered for each procedure. extras/morphine/source/generate_pred_cov.m: extras/morphine/source/generate_call_site_cov.m: extras/morphine/source/coverage_util.m: Generate an initialize/1 predicate that uses map instead of lists. extras/morphine/source/coverage.op: Coverage monitors now output assoc lists.
56 lines
1.4 KiB
Plaintext
56 lines
1.4 KiB
Plaintext
:- import_module map, list, assoc_list.
|
|
|
|
:- type port == trace_port_type.
|
|
:- type proc ---> p(declared_module_name, proc_name).
|
|
:- type pred_crit ---> pc(list(call_number), list(port)).
|
|
:- type accumulator_type == map(proc, pred_crit).
|
|
|
|
filter(Event, Map0, Map) :-
|
|
Port = port(Event),
|
|
Proc = p(decl_module(Event), proc_name(Event)),
|
|
CallN = call(Event),
|
|
( if
|
|
( Port = exit ; Port = fail ),
|
|
pc(CNL0, PL0) = map__search(Map0, Proc)
|
|
then
|
|
( if
|
|
CNL0 = []
|
|
then
|
|
remove_port(Port, PL0, PL)
|
|
else if
|
|
member(CallN, CNL0)
|
|
then
|
|
( if Port = exit then remove_port(exit, PL0, PL) else PL = PL0 )
|
|
else
|
|
% not member(CallN, CNL0) and not (CNL0 = [])
|
|
( if Port = exit then PL = PL0 else remove_port(fail, PL0, PL) )
|
|
),
|
|
( if
|
|
PL = []
|
|
then
|
|
map__delete(Map0, Proc, Map)
|
|
else
|
|
( if
|
|
(Port = exit, not member(CallN, CNL0))
|
|
then
|
|
CNL = [CallN | CNL0]
|
|
else
|
|
CNL = CNL0
|
|
),
|
|
map__update(Map0, Proc, pc(CNL, PL), Map)
|
|
)
|
|
else
|
|
Map = Map0
|
|
).
|
|
|
|
:- pred remove_port(port::in, list(port)::in, list(port)::out) is det.
|
|
remove_port(Port, List0, List) :-
|
|
( if list__delete_first(List0, Port, List1)
|
|
then List = List1 else List = List0 ).
|
|
|
|
:- type collected_type == assoc_list(proc, pred_crit).
|
|
post_process(Map, AssocList) :-
|
|
map__to_assoc_list(Map, AssocList).
|
|
|
|
|