Files
mercury/compiler/prog_detism.m
Zoltan Somogyi 04dec8c205 Carve vartypes.m, prog_detism.m and prog_rename.m out of prog_data.m.
Besides defining most of the types representing the smaller parts of
parse trees (parts smaller than items), prog_data.m also has many utility
predicates that operate on values of these types. Carve the three substantial
clusters of predicates out of prog_data.m, and move them into their own
modules, which are each imported by fewer modules than prog_data.m itself.

compiler/vartypes.m:
    New module containing the vartypes type and the predicates that operate
    on it. The new module has *much* better cohesion than the old prog_data.m.

    The vartypes type does not appear in any parse tree; it is used only
    in the HLDS. So make vartypes.m part of the hlds.m package, not
    parse_tree.m.

    Move three predicates that perform renamings and substitutions on vartypes
    here from prog_type_subst.m, since the latter is part of the parse_tree.m
    package, and thus doesn't have access to hlds.vartypes. Make private
    the service predicate that these three moved predicates used to rely on,
    since it has no other callers.

compiler/prog_detism.m:
    New module containing utility predicates that operate on determinisms
    and determinism components.

compiler/prog_rename.m:
    New module containing utility predicates that rename variables in
    various data structures.

compiler/prog_data.m:
    Remove the stuff now in the three new modules.

compiler/prog_type_subst.m:
    Remove the three predicates now in vartypes.m.

compiler/mercury_to_mercury.m:
    Delete an unneded predicate, which was the only part of this module
    that referred to vartypes.

compiler/prog_type.m:
compiler/builtin_lib_types.m:
compiler/type_util.m:
    Move some utility predicates that refer to vartypes from prog_type.m
    and builtin_lib_types.m (both part of parse_tree.m) to type_util.m
    (part of check_hlds.m).

compiler/parse_tree.m:
compiler/hlds.m:
compiler/notes/compiler_design.html:
    Mention the new modules.

compiler/accumulator.m:
compiler/add_class.m:
compiler/add_clause.m:
compiler/add_foreign_proc.m:
compiler/add_heap_ops.m:
compiler/add_pragma_type_spec.m:
compiler/add_pred.m:
compiler/add_trail_ops.m:
compiler/arg_info.m:
compiler/bytecode_gen.m:
compiler/call_gen.m:
compiler/clause_to_proc.m:
compiler/closure_analysis.m:
compiler/code_info.m:
compiler/code_loc_dep.m:
compiler/common.m:
compiler/complexity.m:
compiler/const_prop.m:
compiler/constraint.m:
compiler/continuation_info.m:
compiler/coverage_profiling.m:
compiler/cse_detection.m:
compiler/ctgc.datastruct.m:
compiler/ctgc.util.m:
compiler/deep_profiling.m:
compiler/deforest.m:
compiler/delay_construct.m:
compiler/delay_partial_inst.m:
compiler/dep_par_conj.m:
compiler/det_analysis.m:
compiler/det_report.m:
compiler/det_util.m:
compiler/disj_gen.m:
compiler/equiv_type_hlds.m:
compiler/erl_call_gen.m:
compiler/erl_code_gen.m:
compiler/erl_code_util.m:
compiler/exception_analysis.m:
compiler/float_regs.m:
compiler/follow_code.m:
compiler/follow_vars.m:
compiler/format_call.m:
compiler/goal_expr_to_goal.m:
compiler/goal_path.m:
compiler/goal_store.m:
compiler/goal_util.m:
compiler/headvar_names.m:
compiler/hhf.m:
compiler/higher_order.m:
compiler/hlds_clauses.m:
compiler/hlds_goal.m:
compiler/hlds_llds.m:
compiler/hlds_out_goal.m:
compiler/hlds_out_module.m:
compiler/hlds_out_pred.m:
compiler/hlds_pred.m:
compiler/hlds_rtti.m:
compiler/inlining.m:
compiler/inst_util.m:
compiler/instmap.m:
compiler/intermod.m:
compiler/interval.m:
compiler/lambda.m:
compiler/lco.m:
compiler/live_vars.m:
compiler/liveness.m:
compiler/lookup_switch.m:
compiler/make_goal.m:
compiler/mark_tail_calls.m:
compiler/ml_accurate_gc.m:
compiler/ml_code_gen.m:
compiler/ml_code_util.m:
compiler/ml_disj_gen.m:
compiler/ml_gen_info.m:
compiler/ml_lookup_switch.m:
compiler/ml_proc_gen.m:
compiler/ml_unify_gen.m:
compiler/mode_constraints.m:
compiler/mode_info.m:
compiler/mode_util.m:
compiler/modecheck_call.m:
compiler/modecheck_conj.m:
compiler/modecheck_goal.m:
compiler/modecheck_unify.m:
compiler/modecheck_util.m:
compiler/modes.m:
compiler/par_loop_control.m:
compiler/pd_info.m:
compiler/pd_util.m:
compiler/polymorphism.m:
compiler/post_typecheck.m:
compiler/prog_rep.m:
compiler/prop_mode_constraints.m:
compiler/purity.m:
compiler/qual_info.m:
compiler/quantification.m:
compiler/rbmm.points_to_graph.m:
compiler/rbmm.points_to_info.m:
compiler/rbmm.region_liveness_info.m:
compiler/rbmm.region_transformation.m:
compiler/saved_vars.m:
compiler/set_of_var.m:
compiler/simplify_goal_call.m:
compiler/simplify_goal_conj.m:
compiler/simplify_goal_disj.m:
compiler/simplify_goal_ite.m:
compiler/simplify_goal_scope.m:
compiler/simplify_goal_switch.m:
compiler/simplify_goal_unify.m:
compiler/simplify_info.m:
compiler/simplify_proc.m:
compiler/size_prof.m:
compiler/ssdebug.m:
compiler/stack_alloc.m:
compiler/stack_layout.m:
compiler/stack_opt.m:
compiler/stm_expand.m:
compiler/store_alloc.m:
compiler/structure_reuse.analysis.m:
compiler/structure_reuse.direct.choose_reuse.m:
compiler/structure_reuse.direct.detect_garbage.m:
compiler/structure_reuse.indirect.m:
compiler/structure_reuse.lbu.m:
compiler/structure_reuse.lfu.m:
compiler/structure_sharing.analysis.m:
compiler/structure_sharing.domain.m:
compiler/switch_detection.m:
compiler/table_gen.m:
compiler/tabling_analysis.m:
compiler/term_constr_build.m:
compiler/term_constr_initial.m:
compiler/term_constr_util.m:
compiler/term_pass1.m:
compiler/term_traversal.m:
compiler/term_util.m:
compiler/trace_gen.m:
compiler/trailing_analysis.m:
compiler/try_expand.m:
compiler/tupling.m:
compiler/type_assign.m:
compiler/type_constraints.m:
compiler/typecheck.m:
compiler/typecheck_errors.m:
compiler/unify_gen.m:
compiler/unify_proc.m:
compiler/unique_modes.m:
compiler/unneeded_code.m:
compiler/untupling.m:
compiler/unused_args.m:
compiler/var_locn.m:
    Conform to the above changes, mostly by importing some of the
    three new modules as well as, or instead of, prog_data.m.
2015-08-09 19:02:12 +10:00

312 lines
13 KiB
Mathematica

%---------------------------------------------------------------------------%
% vim: ft=mercury ts=4 sw=4 et
%---------------------------------------------------------------------------%
% Copyright (C) 1996-2012 The University of Melbourne.
% This file may only be copied under the terms of the GNU General
% Public License - see the file COPYING in the Mercury distribution.
%---------------------------------------------------------------------------%
%
% This module contains types and predicates for working with determinism
% information.
%
%---------------------------------------------------------------------------%
:- module parse_tree.prog_detism.
:- interface.
:- import_module parse_tree.prog_data.
:- import_module maybe.
%---------------------------------------------------------------------------%
% The following predicates implement the tables for computing the
% determinism of compound goals from the determinism of their components.
:- pred det_conjunction_detism(determinism::in, determinism::in,
determinism::out) is det.
:- pred det_par_conjunction_detism(determinism::in, determinism::in,
determinism::out) is det.
:- pred det_switch_detism(determinism::in, determinism::in, determinism::out)
is det.
:- pred det_negation_det(determinism::in, maybe(determinism)::out) is det.
% The following predicates do abstract interpretation to count
% the number of solutions and the possible number of failures.
%
% If the num_solns is at_most_many_cc, this means that the goal might have
% many logical solutions if there were no pruning, but that the goal occurs
% in a single-solution context, so only the first solution will be
% returned.
%
% The reason why we don't throw an exception in det_switch_maxsoln and
% det_disjunction_maxsoln is given in the documentation of the test case
% invalid/magicbox.m.
:- pred det_conjunction_maxsoln(soln_count::in, soln_count::in,
soln_count::out) is det.
:- pred det_conjunction_canfail(can_fail::in, can_fail::in, can_fail::out)
is det.
:- pred det_disjunction_maxsoln(soln_count::in, soln_count::in,
soln_count::out) is det.
:- pred det_disjunction_canfail(can_fail::in, can_fail::in, can_fail::out)
is det.
:- pred det_switch_maxsoln(soln_count::in, soln_count::in, soln_count::out)
is det.
:- pred det_switch_canfail(can_fail::in, can_fail::in, can_fail::out) is det.
%---------------------------------------------------------------------------%
:- type det_comparison
---> first_detism_tighter_than
% The first determinism promises strictly more than the second.
; first_detism_same_as
% The first determinism promises exactly as much as the second.
; first_detism_looser_than
% The first determinism promises strictly less than the second.
; first_detism_incomparable.
% The first determinism promises more than the second in one aspect
% (can_fail or soln_count), but promises less in the other aspect.
:- pred compare_determinisms(determinism::in, determinism::in,
det_comparison::out) is det.
:- type det_component_comparison
---> first_tighter_than
; first_same_as
; first_looser_than.
:- pred compare_canfails(can_fail::in, can_fail::in,
det_component_comparison::out) is det.
:- pred compare_solncounts(soln_count::in, soln_count::in,
det_component_comparison::out) is det.
%---------------------------------------------------------------------------%
:- implementation.
:- import_module require.
%---------------------------------------------------------------------------%
det_conjunction_detism(DetismA, DetismB, Detism) :-
% When figuring out the determinism of a conjunction, if the second goal
% is unreachable, then then the determinism of the conjunction is just
% the determinism of the first goal.
determinism_components(DetismA, CanFailA, MaxSolnA),
(
MaxSolnA = at_most_zero,
Detism = DetismA
;
( MaxSolnA = at_most_one
; MaxSolnA = at_most_many
; MaxSolnA = at_most_many_cc
),
determinism_components(DetismB, CanFailB, MaxSolnB),
det_conjunction_canfail(CanFailA, CanFailB, CanFail),
det_conjunction_maxsoln(MaxSolnA, MaxSolnB, MaxSoln),
determinism_components(Detism, CanFail, MaxSoln)
).
det_par_conjunction_detism(DetismA, DetismB, Detism) :-
% Figuring out the determinism of a parallel conjunction is much easier
% than for a sequential conjunction, since you simply ignore the case
% where the second goal is unreachable. Just do a normal solution count.
determinism_components(DetismA, CanFailA, MaxSolnA),
determinism_components(DetismB, CanFailB, MaxSolnB),
det_conjunction_canfail(CanFailA, CanFailB, CanFail),
det_conjunction_maxsoln(MaxSolnA, MaxSolnB, MaxSoln),
determinism_components(Detism, CanFail, MaxSoln).
det_switch_detism(DetismA, DetismB, Detism) :-
determinism_components(DetismA, CanFailA, MaxSolnA),
determinism_components(DetismB, CanFailB, MaxSolnB),
det_switch_canfail(CanFailA, CanFailB, CanFail),
det_switch_maxsoln(MaxSolnA, MaxSolnB, MaxSoln),
determinism_components(Detism, CanFail, MaxSoln).
det_negation_det(detism_det, yes(detism_failure)).
det_negation_det(detism_semi, yes(detism_semi)).
det_negation_det(detism_multi, no).
det_negation_det(detism_non, no).
det_negation_det(detism_cc_multi, no).
det_negation_det(detism_cc_non, no).
det_negation_det(detism_erroneous, yes(detism_erroneous)).
det_negation_det(detism_failure, yes(detism_det)).
%---------------------------------------------------------------------------%
det_conjunction_maxsoln(at_most_zero, at_most_zero, at_most_zero).
det_conjunction_maxsoln(at_most_zero, at_most_one, at_most_zero).
det_conjunction_maxsoln(at_most_zero, at_most_many_cc, at_most_zero).
det_conjunction_maxsoln(at_most_zero, at_most_many, at_most_zero).
det_conjunction_maxsoln(at_most_one, at_most_zero, at_most_zero).
det_conjunction_maxsoln(at_most_one, at_most_one, at_most_one).
det_conjunction_maxsoln(at_most_one, at_most_many_cc, at_most_many_cc).
det_conjunction_maxsoln(at_most_one, at_most_many, at_most_many).
det_conjunction_maxsoln(at_most_many_cc, at_most_zero, at_most_zero).
det_conjunction_maxsoln(at_most_many_cc, at_most_one, at_most_many_cc).
det_conjunction_maxsoln(at_most_many_cc, at_most_many_cc, at_most_many_cc).
det_conjunction_maxsoln(at_most_many_cc, at_most_many, _) :-
% If the first conjunct could be cc pruned, the second conj ought to have
% been cc pruned too.
unexpected($module, $pred, "many_cc, many").
det_conjunction_maxsoln(at_most_many, at_most_zero, at_most_zero).
det_conjunction_maxsoln(at_most_many, at_most_one, at_most_many).
det_conjunction_maxsoln(at_most_many, at_most_many_cc, at_most_many).
det_conjunction_maxsoln(at_most_many, at_most_many, at_most_many).
det_conjunction_canfail(can_fail, can_fail, can_fail).
det_conjunction_canfail(can_fail, cannot_fail, can_fail).
det_conjunction_canfail(cannot_fail, can_fail, can_fail).
det_conjunction_canfail(cannot_fail, cannot_fail, cannot_fail).
%---------------------------------------------------------------------------%
det_disjunction_maxsoln(at_most_zero, at_most_zero, at_most_zero).
det_disjunction_maxsoln(at_most_zero, at_most_one, at_most_one).
det_disjunction_maxsoln(at_most_zero, at_most_many_cc, at_most_many_cc).
det_disjunction_maxsoln(at_most_zero, at_most_many, at_most_many).
det_disjunction_maxsoln(at_most_one, at_most_zero, at_most_one).
det_disjunction_maxsoln(at_most_one, at_most_one, at_most_many).
det_disjunction_maxsoln(at_most_one, at_most_many_cc, at_most_many_cc).
det_disjunction_maxsoln(at_most_one, at_most_many, at_most_many).
det_disjunction_maxsoln(at_most_many_cc, at_most_zero, at_most_many_cc).
det_disjunction_maxsoln(at_most_many_cc, at_most_one, at_most_many_cc).
det_disjunction_maxsoln(at_most_many_cc, at_most_many_cc, at_most_many_cc).
det_disjunction_maxsoln(at_most_many_cc, at_most_many, at_most_many_cc).
det_disjunction_maxsoln(at_most_many, at_most_zero, at_most_many).
det_disjunction_maxsoln(at_most_many, at_most_one, at_most_many).
det_disjunction_maxsoln(at_most_many, at_most_many_cc, at_most_many_cc).
det_disjunction_maxsoln(at_most_many, at_most_many, at_most_many).
det_disjunction_canfail(can_fail, can_fail, can_fail).
det_disjunction_canfail(can_fail, cannot_fail, cannot_fail).
det_disjunction_canfail(cannot_fail, can_fail, cannot_fail).
det_disjunction_canfail(cannot_fail, cannot_fail, cannot_fail).
%---------------------------------------------------------------------------%
det_switch_maxsoln(at_most_zero, at_most_zero, at_most_zero).
det_switch_maxsoln(at_most_zero, at_most_one, at_most_one).
det_switch_maxsoln(at_most_zero, at_most_many_cc, at_most_many_cc).
det_switch_maxsoln(at_most_zero, at_most_many, at_most_many).
det_switch_maxsoln(at_most_one, at_most_zero, at_most_one).
det_switch_maxsoln(at_most_one, at_most_one, at_most_one).
det_switch_maxsoln(at_most_one, at_most_many_cc, at_most_many_cc).
det_switch_maxsoln(at_most_one, at_most_many, at_most_many).
det_switch_maxsoln(at_most_many_cc, at_most_zero, at_most_many_cc).
det_switch_maxsoln(at_most_many_cc, at_most_one, at_most_many_cc).
det_switch_maxsoln(at_most_many_cc, at_most_many_cc, at_most_many_cc).
det_switch_maxsoln(at_most_many_cc, at_most_many, at_most_many_cc).
det_switch_maxsoln(at_most_many, at_most_zero, at_most_many).
det_switch_maxsoln(at_most_many, at_most_one, at_most_many).
det_switch_maxsoln(at_most_many, at_most_many_cc, at_most_many_cc).
det_switch_maxsoln(at_most_many, at_most_many, at_most_many).
det_switch_canfail(can_fail, can_fail, can_fail).
det_switch_canfail(can_fail, cannot_fail, can_fail).
det_switch_canfail(cannot_fail, can_fail, can_fail).
det_switch_canfail(cannot_fail, cannot_fail, cannot_fail).
%---------------------------------------------------------------------------%
compare_determinisms(DetismA, DetismB, CmpDetism) :-
determinism_components(DetismA, CanFailA, SolnsA),
determinism_components(DetismB, CanFailB, SolnsB),
compare_canfails(CanFailA, CanFailB, CmpCanFail),
compare_solncounts(SolnsA, SolnsB, CmpSolns),
% We can get e.g. tighter canfail and looser solncount
% e.g. for a predicate declared multidet and inferred semidet.
% Therefore the ordering of the following two tests is important:
% we want errors to take precedence over warnings.
(
CmpCanFail = first_tighter_than,
(
( CmpSolns = first_tighter_than
; CmpSolns = first_same_as
),
CmpDetism = first_detism_tighter_than
;
CmpSolns = first_looser_than,
CmpDetism = first_detism_incomparable
)
;
CmpCanFail = first_same_as,
(
CmpSolns = first_tighter_than,
CmpDetism = first_detism_tighter_than
;
CmpSolns = first_same_as,
CmpDetism = first_detism_same_as
;
CmpSolns = first_looser_than,
CmpDetism = first_detism_looser_than
)
;
CmpCanFail = first_looser_than,
(
CmpSolns = first_tighter_than,
CmpDetism = first_detism_incomparable
;
( CmpSolns = first_same_as
; CmpSolns = first_looser_than
),
CmpDetism = first_detism_looser_than
)
).
compare_canfails(cannot_fail, cannot_fail, first_same_as).
compare_canfails(cannot_fail, can_fail, first_tighter_than).
compare_canfails(can_fail, cannot_fail, first_looser_than).
compare_canfails(can_fail, can_fail, first_same_as).
compare_solncounts(at_most_zero, at_most_zero, first_same_as).
compare_solncounts(at_most_zero, at_most_one, first_tighter_than).
compare_solncounts(at_most_zero, at_most_many_cc, first_tighter_than).
compare_solncounts(at_most_zero, at_most_many, first_tighter_than).
compare_solncounts(at_most_one, at_most_zero, first_looser_than).
compare_solncounts(at_most_one, at_most_one, first_same_as).
compare_solncounts(at_most_one, at_most_many_cc, first_tighter_than).
compare_solncounts(at_most_one, at_most_many, first_tighter_than).
compare_solncounts(at_most_many_cc, at_most_zero, first_looser_than).
compare_solncounts(at_most_many_cc, at_most_one, first_looser_than).
compare_solncounts(at_most_many_cc, at_most_many_cc, first_same_as).
compare_solncounts(at_most_many_cc, at_most_many, first_tighter_than).
compare_solncounts(at_most_many, at_most_zero, first_looser_than).
compare_solncounts(at_most_many, at_most_one, first_looser_than).
compare_solncounts(at_most_many, at_most_many_cc, first_looser_than).
compare_solncounts(at_most_many, at_most_many, first_same_as).
%---------------------------------------------------------------------------%
:- end_module parse_tree.prog_detism.
%---------------------------------------------------------------------------%