Files
mercury/tests/general/mode_inf_bug.m
Zoltan Somogyi ecb5e4a9e6 Update the style of many test cases.
tests/declarative_debugger/*.m:
tests/exceptions/*.m:
tests/general/*.m:
tests/grade_subdirs/*.m:
tests/purity/*.m:
tests/submodules/*.m:
tests/typeclasses/*.m:
    Update programming style.

tests/declarative_debugger/*.inp:
    Update line numbers in breakpoint commands.
tests/declarative_debugger/*.exp:
    Update expected line numbers.

tests/exceptions/Mercury.options:
tests/general/Mercury.options:
    Disable some warnings that are irrelevant to the test.
2021-07-25 23:26:17 +10:00

149 lines
3.4 KiB
Mathematica

%---------------------------------------------------------------------------%
% vim: ts=4 sw=4 et ft=mercury
%---------------------------------------------------------------------------%
%
% This is a regression test; mercury 0.6 died with
%
% $ mc --infer-all mode_inf_bug.m
% ...
% Software error: modecheck_set_var_inst: unify_inst failed
%
%---------------------------------------------------------------------------%
:- module mode_inf_bug.
:- interface.
:- import_module io.
:- pred main(io::di, io::uo) is det.
:- implementation.
:- import_module bool.
:- import_module char.
:- import_module int.
:- import_module list.
main(!IO) :-
test1(!IO),
test2(!IO).
%%% Test suite -------------------------------------------------------
%% For an alternative, see the definition of cpu_time/3 in "The Craft
%% of Prolog", by Richard A. O'Keefe.
% :- use_module(library(benchmark), [time/3]).
test1(!IO) :-
test_all(1000, 10, 10, !IO).
test2(!IO) :-
test_all(10000, 10, 10, !IO).
test_all(ListSize, Count, InternalCount, !IO) :-
write_s("Non-meta predicate:", !IO),
time(test_is_a_list_1(ListSize), Count, InternalCount, !IO),
io.nl(!IO),
write_s("Non-meta predicate with call:", !IO),
time(test_is_a_list_2(ListSize), Count, InternalCount, !IO),
io.nl(!IO),
write_s("Meta-predicate with call:", !IO),
time(test_map_list_1(ListSize), Count, InternalCount, !IO),
io.nl(!IO),
write_s("Meta-predicate with hook:", !IO),
time(test_map_list_2(ListSize), Count, InternalCount, !IO).
:- mode test_is_a_list_1(in) is semidet.
test_is_a_list_1(N) :-
gen_a_list(N, L),
is_a_list_1(L).
:- mode test_is_a_list_2(in) is semidet.
test_is_a_list_2(N) :-
gen_a_list(N, L),
is_a_list_2(L).
:- mode test_map_list_1(in) is semidet.
test_map_list_1(N) :-
gen_a_list(N, L),
map_list_1(L, is_a).
:- mode test_map_list_2(in) is semidet.
test_map_list_2(N) :-
gen_a_list(N, L),
map_list_2(L, hook_is_a).
time(Pred, Count, _InternalCount, !IO) :-
( if Pred then
write_s("yes", !IO)
else
write_s("no", !IO)
),
io.nl(!IO),
write_s("Count = ", !IO),
io.write_int(Count, !IO),
io.nl(!IO).
write_s(S, !IO) :-
io.write_string(S, !IO).
:- type hook
---> hook_is_a.
%---------------------------------------------------------------------------%
%% Description: Speed tests for meta predicates.
%%% Simple test predicate --------------------------------------------
:- mode is_a(in) is semidet.
is_a(a).
%%% Non-meta predicate -----------------------------------------------
is_a_list_1([]).
is_a_list_1([F | R]) :-
is_a(F),
is_a_list_1(R).
%%% Non-meta predicate with call -------------------------------------
is_a_list_2([]).
is_a_list_2([F | R]) :-
call(is_a(F)),
is_a_list_2(R).
%%% Meta predicate with call -----------------------------------------
map_list_1([], _G).
map_list_1([F | R], G) :-
call(G, F),
map_list_1(R, G).
%%% Meta predicate with hook -----------------------------------------
map_list_2([], _G).
map_list_2([F | R], G) :-
map_list_hook(G, F),
map_list_2(R, G).
map_list_hook(hook_is_a, X) :-
is_a(X).
%%% Generate a list of atoms -----------------------------------------
gen_a_list(N, L) :-
gen_a_list(N, [], L).
gen_a_list(N, L0, L) :-
( if N = 0 then
L = L0
else
N1 = N - 1,
gen_a_list(N1, [a | L0], L)
).
%---------------------------------------------------------------------------%