Files
mercury/compiler/goal_path.m
Julien Fischer 459847a064 Move the univ, maybe, pair and unit types from std_util into their own
Estimated hours taken: 18
Branches: main

Move the univ, maybe, pair and unit types from std_util into their own
modules.  std_util still contains the general purpose higher-order programming
constructs.

library/std_util.m:
	Move univ, maybe, pair and unit (plus any other related types
	and procedures) into their own modules.

library/maybe.m:
	New module.  This contains the maybe and maybe_error types and
	the associated procedures.

library/pair.m:
	New module.  This contains the pair type and associated procedures.

library/unit.m:
	New module. This contains the types unit/0 and unit/1.

library/univ.m:
	New module. This contains the univ type and associated procedures.

library/library.m:
	Add the new modules.

library/private_builtin.m:
	Update the declaration of the type_ctor_info struct for univ.

runtime/mercury.h:
	Update the declaration for the type_ctor_info struct for univ.

runtime/mercury_mcpp.h:
runtime/mercury_hlc_types.h:
	Update the definition of MR_Univ.

runtime/mercury_init.h:
	Fix a comment: ML_type_name is now exported from type_desc.m.

compiler/mlds_to_il.m:
	Update the the name of the module that defines univs (which are
	handled specially by the il code generator.)

library/*.m:
compiler/*.m:
browser/*.m:
mdbcomp/*.m:
profiler/*.m:
deep_profiler/*.m:
	Conform to the above changes.  Import the new modules where they
	are needed; don't import std_util where it isn't needed.

	Fix formatting in lots of modules.  Delete duplicate module
	imports.

tests/*:
	Update the test suite to confrom to the above changes.
2006-03-29 08:09:58 +00:00

239 lines
8.7 KiB
Mathematica

%-----------------------------------------------------------------------------%
% vim: ft=mercury ts=4 sw=4 et
%-----------------------------------------------------------------------------%
% Copyright (C) 1997-2006 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.
%-----------------------------------------------------------------------------%
% File: goal_path.m.
% Main author: zs.
% This module looks after goal paths, which associate each goal with its
% position in a procedure definition,
%-----------------------------------------------------------------------------%
:- module check_hlds.goal_path.
:- interface.
:- import_module hlds.hlds_goal.
:- import_module hlds.hlds_pred.
:- import_module hlds.hlds_module.
:- import_module parse_tree.prog_data.
:- import_module bool.
%-----------------------------------------------------------------------------%
% IMPORTANT: the type constraint_id in hlds_data.m makes use of
% goal_paths to identify constraints between the typechecking pass
% and the polymorphism pass. For this reason, goal paths should not
% be recalculated anywhere between these two passes. See the XXX
% comment near the declaration of constraint_id.
%
:- pred fill_goal_path_slots(module_info::in, proc_info::in, proc_info::out)
is det.
% Fill in the goal_paths for goals in the clauses_info of the predicate.
% Clauses are given goal paths `disj(1)', ..., `disj(N)'. If the bool
% argument is true then the goal paths are stored in a form where any
% prefix consisting of `disj(_)', `neg', `exist(_)' and `ite_else'
% components is removed. This is used to optimise the constraint-based
% mode analysis where the instantiatedness of a variable at such a goal
% path is always equivalent to its instantiatedness at the parent goal
% path.
%
:- pred fill_goal_path_slots_in_clauses(module_info::in, bool::in,
pred_info::in, pred_info::out) is det.
:- pred fill_goal_path_slots_in_goal(hlds_goal::in, vartypes::in,
module_info::in, hlds_goal::out) is det.
%-----------------------------------------------------------------------------%
%-----------------------------------------------------------------------------%
:- implementation.
:- import_module check_hlds.type_util.
:- import_module hlds.hlds_clauses.
:- import_module hlds.hlds_data.
:- import_module hlds.hlds_goal.
:- import_module libs.compiler_util.
:- import_module parse_tree.prog_data.
:- import_module char.
:- import_module int.
:- import_module list.
:- import_module map.
:- import_module pair.
%-----------------------------------------------------------------------------%
:- type slot_info
---> slot_info(
vartypes :: vartypes,
module_info :: module_info,
omit_mode_equiv_prefix :: bool
).
fill_goal_path_slots(ModuleInfo, !Proc) :-
proc_info_get_goal(!.Proc, Goal0),
proc_info_get_vartypes(!.Proc, VarTypes),
fill_goal_path_slots_in_goal(Goal0, VarTypes, ModuleInfo, Goal),
proc_info_set_goal(Goal, !Proc).
fill_goal_path_slots_in_clauses(ModuleInfo, OmitModeEquivPrefix, !PredInfo) :-
pred_info_clauses_info(!.PredInfo, ClausesInfo0),
clauses_info_clauses_only(ClausesInfo0, Clauses0),
clauses_info_get_vartypes(ClausesInfo0, VarTypes),
SlotInfo = slot_info(VarTypes, ModuleInfo, OmitModeEquivPrefix),
list.map_foldl(fill_slots_in_clause(SlotInfo), Clauses0, Clauses, 1, _),
clauses_info_set_clauses(Clauses, ClausesInfo0, ClausesInfo),
pred_info_set_clauses_info(ClausesInfo, !PredInfo).
:- pred fill_slots_in_clause(slot_info::in, clause::in, clause::out,
int::in, int::out) is det.
fill_slots_in_clause(SlotInfo, Clause0, Clause, ClauseNum, ClauseNum + 1) :-
Clause0 = clause(ProcIds, Goal0, Lang, Context),
fill_goal_slots([disj(ClauseNum)], SlotInfo, Goal0, Goal),
Clause = clause(ProcIds, Goal, Lang, Context).
fill_goal_path_slots_in_goal(Goal0, VarTypes, ModuleInfo, Goal) :-
SlotInfo = slot_info(VarTypes, ModuleInfo, no),
fill_goal_slots([], SlotInfo, Goal0, Goal).
:- pred fill_goal_slots(goal_path::in, slot_info::in,
hlds_goal::in, hlds_goal::out) is det.
fill_goal_slots(Path0, SlotInfo, Expr0 - Info0, Expr - Info) :-
OmitModeEquivPrefix = SlotInfo ^ omit_mode_equiv_prefix,
(
OmitModeEquivPrefix = yes,
list.takewhile(mode_equiv_step, Path0, _, Path)
;
OmitModeEquivPrefix = no,
Path = Path0
),
goal_info_set_goal_path(Path, Info0, Info),
fill_expr_slots(Info, Path0, SlotInfo, Expr0, Expr).
:- pred mode_equiv_step(goal_path_step::in) is semidet.
mode_equiv_step(Step) :-
( Step = disj(_)
; Step = neg
; Step = scope(_)
; Step = ite_else
).
:- pred fill_expr_slots(hlds_goal_info::in, goal_path::in, slot_info::in,
hlds_goal_expr::in, hlds_goal_expr::out) is det.
fill_expr_slots(GoalInfo, Path0, SlotInfo, Goal0, Goal) :-
(
Goal0 = conj(ConjType, Goals0),
fill_conj_slots(Path0, 0, SlotInfo, Goals0, Goals),
Goal = conj(ConjType, Goals)
;
Goal0 = disj(Goals0),
fill_disj_slots(Path0, 0, SlotInfo, Goals0, Goals),
Goal = disj(Goals)
;
Goal0 = switch(Var, CanFail, Cases0),
VarTypes = SlotInfo ^ vartypes,
ModuleInfo = SlotInfo ^ module_info,
map.lookup(VarTypes, Var, Type),
( switch_type_num_functors(ModuleInfo, Type, NumFunctors) ->
NumCases = NumFunctors
;
NumCases = -1
),
fill_switch_slots(Path0, 0, NumCases, SlotInfo, Cases0, Cases),
Goal = switch(Var, CanFail, Cases)
;
Goal0 = not(SubGoal0),
fill_goal_slots([neg | Path0], SlotInfo, SubGoal0, SubGoal),
Goal = not(SubGoal)
;
Goal0 = scope(Reason, SubGoal0),
SubGoal0 = _ - InnerInfo,
goal_info_get_determinism(GoalInfo, OuterDetism),
goal_info_get_determinism(InnerInfo, InnerDetism),
( InnerDetism = OuterDetism ->
MaybeCut = no_cut
;
MaybeCut = cut
),
fill_goal_slots([scope(MaybeCut) | Path0], SlotInfo,
SubGoal0, SubGoal),
Goal = scope(Reason, SubGoal)
;
Goal0 = if_then_else(A, Cond0, Then0, Else0),
fill_goal_slots([ite_cond | Path0], SlotInfo, Cond0, Cond),
fill_goal_slots([ite_then | Path0], SlotInfo, Then0, Then),
fill_goal_slots([ite_else | Path0], SlotInfo, Else0, Else),
Goal = if_then_else(A, Cond, Then, Else)
;
Goal0 = unify(LHS, RHS0, Mode, Kind, Context),
( RHS0 = lambda_goal(A, B, C, D, E, F, G, LambdaGoal0) ->
fill_goal_slots(Path0, SlotInfo, LambdaGoal0, LambdaGoal),
RHS = lambda_goal(A, B, C, D, E, F, G, LambdaGoal)
;
RHS = RHS0
),
Goal = unify(LHS, RHS, Mode, Kind, Context)
;
Goal0 = call(_, _, _, _, _, _),
Goal = Goal0
;
Goal0 = generic_call(_, _, _, _),
Goal = Goal0
;
Goal0 = foreign_proc(_, _, _, _, _, _),
Goal = Goal0
;
Goal0 = shorthand(_),
% These should have been expanded out by now.
unexpected(this_file, "fill_expr_slots: unexpected shorthand")
).
:- pred fill_conj_slots(goal_path::in, int::in, slot_info::in,
list(hlds_goal)::in, list(hlds_goal)::out) is det.
fill_conj_slots(_, _, _, [], []).
fill_conj_slots(Path0, N0, SlotInfo, [Goal0 | Goals0], [Goal | Goals]) :-
N1 = N0 + 1,
fill_goal_slots([conj(N1) | Path0], SlotInfo, Goal0, Goal),
fill_conj_slots(Path0, N1, SlotInfo, Goals0, Goals).
:- pred fill_disj_slots(goal_path::in, int::in, slot_info::in,
list(hlds_goal)::in, list(hlds_goal)::out) is det.
fill_disj_slots(_, _, _, [], []).
fill_disj_slots(Path0, N0, SlotInfo, [Goal0 | Goals0], [Goal | Goals]) :-
N1 = N0 + 1,
fill_goal_slots([disj(N1) | Path0], SlotInfo, Goal0, Goal),
fill_disj_slots(Path0, N1, SlotInfo, Goals0, Goals).
:- pred fill_switch_slots(goal_path::in, int::in, int::in, slot_info::in,
list(case)::in, list(case)::out) is det.
fill_switch_slots(_, _, _, _, [], []).
fill_switch_slots(Path0, N0, NumCases, SlotInfo,
[case(A, Goal0) | Cases0], [case(A, Goal) | Cases]) :-
N1 = N0 + 1,
fill_goal_slots([switch(N1, NumCases) | Path0], SlotInfo, Goal0, Goal),
fill_switch_slots(Path0, N1, NumCases, SlotInfo, Cases0, Cases).
%-----------------------------------------------------------------------------%
:- func this_file = string.
this_file = "goal_path.m".
%-----------------------------------------------------------------------------%
:- end_module goal_path.
%-----------------------------------------------------------------------------%