mirror of
https://github.com/Mercury-Language/mercury.git
synced 2025-12-12 20:34:19 +00:00
Estimated hours taken: 4 Branches: main compiler/prog_data.m: Make vartypes an abstract data type, in preparation for exploring better representations for it. compiler/mode_util.m: Provide two different versions of a predicate. The generic version continues to use map lookups. The other version knows it works on prog_vars, so it can use the abstract operations on them provided by prog_data.m. compiler/accumulator.m: compiler/add_class.m: compiler/add_heap_ops.m: compiler/add_pragma.m: compiler/add_pred.m: compiler/add_trail_ops.m: compiler/arg_info.m: compiler/builtin_lib_types.m: compiler/bytecode_gen.m: compiler/call_gen.m: compiler/clause_to_proc.m: compiler/closure_analysis.m: compiler/code_info.m: compiler/common.m: compiler/complexity.m: compiler/const_prop.m: compiler/constraint.m: compiler/continuation_info.m: compiler/cse_detection.m: compiler/ctgc.datastruct.m: compiler/ctgc.util.m: compiler/deep_profiling.m: compiler/deforest.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_vars.m: compiler/format_call.m: compiler/goal_path.m: compiler/goal_util.m: compiler/hhf.m: compiler/higher_order.m: compiler/hlds_clauses.m: compiler/hlds_goal.m: compiler/hlds_out_goal.m: compiler/hlds_out_pred.m: compiler/hlds_pred.m: compiler/hlds_rtti.m: compiler/inlining.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/mercury_to_mercury.m: compiler/ml_accurate_gc.m: compiler/ml_closure_gen.m: compiler/ml_code_gen.m: compiler/ml_code_util.m: compiler/ml_disj_gen.m: compiler/ml_lookup_switch.m: compiler/ml_proc_gen.m: compiler/ml_unify_gen.m: compiler/mode_info.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_type_subst.m: compiler/prop_mode_constraints.m: compiler/purity.m: compiler/qual_info.m: compiler/rbmm.points_to_info.m: compiler/rbmm.region_liveness_info.m: compiler/rbmm.region_transformation.m: compiler/saved_vars.m: compiler/simplify.m: compiler/size_prof.m: compiler/ssdebug.m: compiler/stack_alloc.m: compiler/stack_opt.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_sharing.analysis.m: compiler/structure_sharing.domain.m: compiler/switch_detection.m: compiler/table_gen.m: compiler/term_constr_build.m: compiler/term_constr_util.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_constraints.m: compiler/type_util.m: compiler/typecheck.m: compiler/typecheck_errors.m: compiler/typecheck_info.m: compiler/unify_gen.m: compiler/unify_proc.m: compiler/unique_modes.m: compiler/untupling.m: compiler/unused_args.m: compiler/var_locn.m: Conform to the above. compiler/prog_type.m: compiler/rbmm.points_to_graph.m: Conform to the above. Move some comments where they belong. compiler/stm_expand.m: Conform to the above. Do not export a predicate that is not used outside this module. Disable some debugging output unless it is asked for. Remove unnecessary prefixes on variable names. library/version_array.m: Instead writing code for field access lookalike functions and defining lookup, set etc in terms of them, write code for lookup, set etc, and define the field access lookalike functions in terms of them. Change argument orders of some internal predicates to be more state variable friendly. Fix typos in comments. tests/hard_coded/version_array_test.exp: Conform to the change to version_array.m.
463 lines
20 KiB
Mathematica
463 lines
20 KiB
Mathematica
%-----------------------------------------------------------------------------%
|
|
% vim: ft=mercury ts=4 sw=4 et
|
|
%-----------------------------------------------------------------------------%
|
|
% Copyright (C) 1997-2012 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 ids, which give every goal a unique id within
|
|
% its procedure definition, and goal paths, which map each goal id to its
|
|
% goal's position in the procedure definition.
|
|
%
|
|
%-----------------------------------------------------------------------------%
|
|
%-----------------------------------------------------------------------------%
|
|
|
|
:- module hlds.goal_path.
|
|
:- interface.
|
|
|
|
:- import_module hlds.hlds_clauses.
|
|
:- import_module hlds.hlds_goal.
|
|
:- import_module hlds.hlds_module.
|
|
:- import_module hlds.hlds_pred.
|
|
:- import_module mdbcomp.goal_path.
|
|
:- import_module parse_tree.
|
|
:- import_module parse_tree.prog_data.
|
|
|
|
%-----------------------------------------------------------------------------%
|
|
|
|
% IMPORTANT: the type constraint_id in hlds_data.m makes use of goal ids
|
|
% to identify goals that impose constraints between the typechecking pass
|
|
% and the polymorphism pass. For this reason, goal ids should not be
|
|
% recalculated anywhere between these two passes. See the XXX comment
|
|
% near the declaration of constraint_id.
|
|
%
|
|
:- pred fill_goal_id_slots_in_proc(module_info::in,
|
|
containing_goal_map::out, proc_info::in, proc_info::out) is det.
|
|
|
|
:- pred fill_goal_id_slots_in_proc_body(module_info::in, vartypes::in,
|
|
containing_goal_map::out, hlds_goal::in, hlds_goal::out) is det.
|
|
|
|
% Fill in the goal_ids for goals in the clauses_info.
|
|
% Clauses are given goal paths `disj(1)', ..., `disj(N)'.
|
|
%
|
|
:- pred fill_goal_id_slots_in_clauses(module_info::in,
|
|
containing_goal_map::out, clauses_info::in, clauses_info::out) is det.
|
|
|
|
%-----------------------------------------------------------------------------%
|
|
|
|
% Fill in the goal path slots in the given procedure.
|
|
% This predicate is here ONLY to support the RBMM and GTGC modules,
|
|
% which are hard to transition to make use of goal_ids instead;
|
|
% all new code should instead use the predicates above that fill in
|
|
% the goal_id slots instead.
|
|
%
|
|
:- pred fill_goal_path_slots_in_proc(module_info::in,
|
|
proc_info::in, proc_info::out) is det.
|
|
|
|
%-----------------------------------------------------------------------------%
|
|
%-----------------------------------------------------------------------------%
|
|
|
|
:- implementation.
|
|
|
|
:- import_module check_hlds.type_util.
|
|
:- import_module hlds.hlds_goal.
|
|
:- import_module mdbcomp.
|
|
:- import_module parse_tree.prog_data.
|
|
|
|
:- import_module int.
|
|
:- import_module list.
|
|
:- import_module map.
|
|
:- import_module maybe.
|
|
:- import_module require.
|
|
|
|
%-----------------------------------------------------------------------------%
|
|
|
|
:- type slot_info
|
|
---> slot_info(
|
|
slot_info_module_info :: module_info,
|
|
slot_info_vartypes :: vartypes
|
|
).
|
|
|
|
fill_goal_id_slots_in_proc(ModuleInfo, ContainingGoalMap, !ProcInfo) :-
|
|
proc_info_get_vartypes(!.ProcInfo, VarTypes),
|
|
proc_info_get_goal(!.ProcInfo, Goal0),
|
|
fill_goal_id_slots_in_proc_body(ModuleInfo, VarTypes,
|
|
ContainingGoalMap, Goal0, Goal),
|
|
proc_info_set_goal(Goal, !ProcInfo).
|
|
|
|
fill_goal_id_slots_in_proc_body(ModuleInfo, VarTypes, ContainingGoalMap,
|
|
Goal0, Goal) :-
|
|
SlotInfo = slot_info(ModuleInfo, VarTypes),
|
|
fill_goal_id_slots(SlotInfo, whole_body_goal, 0, _,
|
|
map.init, ContainingGoalMap, Goal0, Goal).
|
|
|
|
fill_goal_id_slots_in_clauses(ModuleInfo, ContainingGoalMap,
|
|
ClausesInfo0, ClausesInfo) :-
|
|
clauses_info_get_clauses_rep(ClausesInfo0, ClausesRep0, ItemNumbers),
|
|
get_clause_list(ClausesRep0, Clauses0),
|
|
clauses_info_get_vartypes(ClausesInfo0, VarTypes),
|
|
SlotInfo = slot_info(ModuleInfo, VarTypes),
|
|
list.map_foldl3(fill_slots_in_clause(SlotInfo),
|
|
Clauses0, Clauses, 1, _, 1, _, map.init, ContainingGoalMap),
|
|
set_clause_list(Clauses, ClausesRep),
|
|
clauses_info_set_clauses_rep(ClausesRep, ItemNumbers,
|
|
ClausesInfo0, ClausesInfo).
|
|
|
|
:- pred fill_slots_in_clause(slot_info::in, clause::in, clause::out,
|
|
int::in, int::out, int::in, int::out,
|
|
containing_goal_map::in, containing_goal_map::out) is det.
|
|
|
|
fill_slots_in_clause(SlotInfo, Clause0, Clause, !GoalNum, !ClauseNum,
|
|
!ContainingGoalMap) :-
|
|
Goal0 = Clause0 ^ clause_body,
|
|
ContainingGoal = containing_goal(whole_body_goal_id,
|
|
step_disj(!.ClauseNum)),
|
|
!:ClauseNum = !.ClauseNum + 1,
|
|
fill_goal_id_slots(SlotInfo, ContainingGoal, !GoalNum, !ContainingGoalMap,
|
|
Goal0, Goal),
|
|
Clause = Clause0 ^ clause_body := Goal.
|
|
|
|
fill_goal_path_slots_in_proc(ModuleInfo, !Proc) :-
|
|
proc_info_get_goal(!.Proc, Goal0),
|
|
proc_info_get_vartypes(!.Proc, VarTypes),
|
|
SlotInfo = slot_info(ModuleInfo, VarTypes),
|
|
fill_goal_path_slots(rgp_nil, SlotInfo, Goal0, Goal),
|
|
proc_info_set_goal(Goal, !Proc).
|
|
|
|
%-----------------------------------------------------------------------------%
|
|
|
|
:- pred fill_goal_id_slots(slot_info::in, containing_goal::in,
|
|
int::in, int::out, containing_goal_map::in, containing_goal_map::out,
|
|
hlds_goal::in, hlds_goal::out) is det.
|
|
|
|
fill_goal_id_slots(SlotInfo, ContainingGoal, !GoalNum, !ContainingGoalMap,
|
|
Goal0, Goal) :-
|
|
Goal0 = hlds_goal(GoalExpr0, GoalInfo0),
|
|
GoalId = goal_id(!.GoalNum),
|
|
!:GoalNum = !.GoalNum + 1,
|
|
goal_info_set_goal_id(GoalId, GoalInfo0, GoalInfo),
|
|
map.det_insert(GoalId, ContainingGoal, !ContainingGoalMap),
|
|
(
|
|
( GoalExpr0 = plain_call(_, _, _, _, _, _)
|
|
; GoalExpr0 = generic_call(_, _, _, _, _)
|
|
; GoalExpr0 = call_foreign_proc(_, _, _, _, _, _, _)
|
|
),
|
|
GoalExpr = GoalExpr0
|
|
;
|
|
GoalExpr0 = unify(LHS, RHS0, Mode, Kind, Context),
|
|
(
|
|
RHS0 = rhs_lambda_goal(Purity, Groundness, PredOrFunc, EvalMethod,
|
|
NonLocals, QuantVars, LambdaModes, Detism, LambdaGoal0),
|
|
fill_goal_id_slots(SlotInfo,
|
|
containing_goal(GoalId, step_lambda),
|
|
!GoalNum, !ContainingGoalMap, LambdaGoal0, LambdaGoal),
|
|
RHS = rhs_lambda_goal(Purity, Groundness, PredOrFunc, EvalMethod,
|
|
NonLocals, QuantVars, LambdaModes, Detism, LambdaGoal),
|
|
GoalExpr = unify(LHS, RHS, Mode, Kind, Context)
|
|
;
|
|
( RHS0 = rhs_var(_)
|
|
; RHS0 = rhs_functor(_, _, _)
|
|
),
|
|
GoalExpr = GoalExpr0
|
|
)
|
|
;
|
|
GoalExpr0 = conj(ConjType, Goals0),
|
|
fill_conj_id_slots(SlotInfo, GoalId, 0, !GoalNum, !ContainingGoalMap,
|
|
Goals0, Goals),
|
|
GoalExpr = conj(ConjType, Goals)
|
|
;
|
|
GoalExpr0 = disj(Goals0),
|
|
fill_disj_id_slots(SlotInfo, GoalId, 0, !GoalNum, !ContainingGoalMap,
|
|
Goals0, Goals),
|
|
GoalExpr = disj(Goals)
|
|
;
|
|
GoalExpr0 = switch(Var, CanFail, Cases0),
|
|
VarTypes = SlotInfo ^ slot_info_vartypes,
|
|
ModuleInfo = SlotInfo ^ slot_info_module_info,
|
|
lookup_var_type(VarTypes, Var, Type),
|
|
( switch_type_num_functors(ModuleInfo, Type, NumFunctors) ->
|
|
MaybeNumFunctors = known_num_functors_in_type(NumFunctors)
|
|
;
|
|
MaybeNumFunctors = unknown_num_functors_in_type
|
|
),
|
|
fill_switch_id_slots(SlotInfo, GoalId, 0, MaybeNumFunctors, !GoalNum,
|
|
!ContainingGoalMap, Cases0, Cases),
|
|
GoalExpr = switch(Var, CanFail, Cases)
|
|
;
|
|
GoalExpr0 = negation(SubGoal0),
|
|
fill_goal_id_slots(SlotInfo, containing_goal(GoalId, step_neg),
|
|
!GoalNum, !ContainingGoalMap, SubGoal0, SubGoal),
|
|
GoalExpr = negation(SubGoal)
|
|
;
|
|
GoalExpr0 = scope(Reason, SubGoal0),
|
|
% We should consider not filling in the goal path slots inside
|
|
% from_ground_term_construct scopes, since we do not use them
|
|
% for anything.
|
|
SubGoal0 = hlds_goal(_, InnerInfo),
|
|
OuterDetism = goal_info_get_determinism(GoalInfo),
|
|
InnerDetism = goal_info_get_determinism(InnerInfo),
|
|
( InnerDetism = OuterDetism ->
|
|
MaybeCut = scope_is_no_cut
|
|
;
|
|
MaybeCut = scope_is_cut
|
|
),
|
|
fill_goal_id_slots(SlotInfo,
|
|
containing_goal(GoalId, step_scope(MaybeCut)),
|
|
!GoalNum, !ContainingGoalMap, SubGoal0, SubGoal),
|
|
GoalExpr = scope(Reason, SubGoal)
|
|
;
|
|
GoalExpr0 = if_then_else(A, Cond0, Then0, Else0),
|
|
fill_goal_id_slots(SlotInfo, containing_goal(GoalId, step_ite_cond),
|
|
!GoalNum, !ContainingGoalMap, Cond0, Cond),
|
|
fill_goal_id_slots(SlotInfo, containing_goal(GoalId, step_ite_then),
|
|
!GoalNum, !ContainingGoalMap, Then0, Then),
|
|
fill_goal_id_slots(SlotInfo, containing_goal(GoalId, step_ite_else),
|
|
!GoalNum, !ContainingGoalMap, Else0, Else),
|
|
GoalExpr = if_then_else(A, Cond, Then, Else)
|
|
;
|
|
GoalExpr0 = shorthand(ShortHand0),
|
|
(
|
|
ShortHand0 = atomic_goal(GoalType, Outer, Inner, MaybeOutputVars,
|
|
MainGoal0, OrElseGoals0, OrElseInners),
|
|
fill_goal_id_slots(SlotInfo,
|
|
containing_goal(GoalId, step_atomic_main),
|
|
!GoalNum, !ContainingGoalMap, MainGoal0, MainGoal),
|
|
fill_orelse_id_slots(SlotInfo, GoalId, 0, !GoalNum,
|
|
!ContainingGoalMap, OrElseGoals0, OrElseGoals),
|
|
ShortHand = atomic_goal(GoalType, Outer, Inner, MaybeOutputVars,
|
|
MainGoal, OrElseGoals, OrElseInners)
|
|
;
|
|
ShortHand0 = try_goal(MaybeIO, ResultVar, SubGoal0),
|
|
fill_goal_id_slots(SlotInfo, containing_goal(GoalId, step_try),
|
|
!GoalNum, !ContainingGoalMap, SubGoal0, SubGoal),
|
|
ShortHand = try_goal(MaybeIO, ResultVar, SubGoal)
|
|
;
|
|
ShortHand0 = bi_implication(_, _),
|
|
% These should have been expanded out by now.
|
|
unexpected($module, $pred, "bi_implication")
|
|
),
|
|
GoalExpr = shorthand(ShortHand)
|
|
),
|
|
Goal = hlds_goal(GoalExpr, GoalInfo).
|
|
|
|
:- pred fill_conj_id_slots(slot_info::in, goal_id::in, int::in,
|
|
int::in, int::out, containing_goal_map::in, containing_goal_map::out,
|
|
list(hlds_goal)::in, list(hlds_goal)::out) is det.
|
|
|
|
fill_conj_id_slots(_, _, _, !GoalNum, !ContainingGoalMap, [], []).
|
|
fill_conj_id_slots(SlotInfo, GoalId, N0, !GoalNum, !ContainingGoalMap,
|
|
[Goal0 | Goals0], [Goal | Goals]) :-
|
|
N1 = N0 + 1,
|
|
ContainingGoal = containing_goal(GoalId, step_conj(N1)),
|
|
fill_goal_id_slots(SlotInfo, ContainingGoal, !GoalNum, !ContainingGoalMap,
|
|
Goal0, Goal),
|
|
fill_conj_id_slots(SlotInfo, GoalId, N1, !GoalNum, !ContainingGoalMap,
|
|
Goals0, Goals).
|
|
|
|
:- pred fill_disj_id_slots(slot_info::in, goal_id::in, int::in,
|
|
int::in, int::out, containing_goal_map::in, containing_goal_map::out,
|
|
list(hlds_goal)::in, list(hlds_goal)::out) is det.
|
|
|
|
fill_disj_id_slots(_, _, _, !GoalNum, !ContainingGoalMap, [], []).
|
|
fill_disj_id_slots(SlotInfo, GoalId, N0, !GoalNum, !ContainingGoalMap,
|
|
[Goal0 | Goals0], [Goal | Goals]) :-
|
|
N1 = N0 + 1,
|
|
ContainingGoal = containing_goal(GoalId, step_disj(N1)),
|
|
fill_goal_id_slots(SlotInfo, ContainingGoal, !GoalNum, !ContainingGoalMap,
|
|
Goal0, Goal),
|
|
fill_disj_id_slots(SlotInfo, GoalId, N1, !GoalNum, !ContainingGoalMap,
|
|
Goals0, Goals).
|
|
|
|
:- pred fill_switch_id_slots(slot_info::in, goal_id::in,
|
|
int::in, maybe_switch_num_functors::in, int::in, int::out,
|
|
containing_goal_map::in, containing_goal_map::out,
|
|
list(case)::in, list(case)::out) is det.
|
|
|
|
fill_switch_id_slots(_, _, _, _, !GoalNum, !ContainingGoalMap, [], []).
|
|
fill_switch_id_slots(SlotInfo, GoalId, N0, MaybeNumFunctors,
|
|
!GoalNum, !ContainingGoalMap, [Case0 | Cases0], [Case | Cases]) :-
|
|
Case0 = case(MainConsId, OtherConsIds, Goal0),
|
|
N1 = N0 + 1,
|
|
ContainingGoal =
|
|
containing_goal(GoalId, step_switch(N1, MaybeNumFunctors)),
|
|
fill_goal_id_slots(SlotInfo, ContainingGoal, !GoalNum, !ContainingGoalMap,
|
|
Goal0, Goal),
|
|
Case = case(MainConsId, OtherConsIds, Goal),
|
|
fill_switch_id_slots(SlotInfo, GoalId, N1, MaybeNumFunctors,
|
|
!GoalNum, !ContainingGoalMap, Cases0, Cases).
|
|
|
|
:- pred fill_orelse_id_slots(slot_info::in, goal_id::in, int::in,
|
|
int::in, int::out, containing_goal_map::in, containing_goal_map::out,
|
|
list(hlds_goal)::in, list(hlds_goal)::out) is det.
|
|
|
|
fill_orelse_id_slots(_, _, _, !GoalNum, !ContainingGoalMap, [], []).
|
|
fill_orelse_id_slots(SlotInfo, GoalId, N0, !GoalNum, !ContainingGoalMap,
|
|
[Goal0 | Goals0], [Goal | Goals]) :-
|
|
N1 = N0 + 1,
|
|
ContainingGoal = containing_goal(GoalId, step_atomic_orelse(N1)),
|
|
fill_goal_id_slots(SlotInfo, ContainingGoal, !GoalNum, !ContainingGoalMap,
|
|
Goal0, Goal),
|
|
fill_orelse_id_slots(SlotInfo, GoalId, N1, !GoalNum, !ContainingGoalMap,
|
|
Goals0, Goals).
|
|
|
|
%-----------------------------------------------------------------------------%
|
|
|
|
:- pred fill_goal_path_slots(reverse_goal_path::in, slot_info::in,
|
|
hlds_goal::in, hlds_goal::out) is det.
|
|
|
|
fill_goal_path_slots(RevPath0, SlotInfo, Goal0, Goal) :-
|
|
Goal0 = hlds_goal(GoalExpr0, GoalInfo0),
|
|
goal_info_set_reverse_goal_path(RevPath0, GoalInfo0, GoalInfo),
|
|
(
|
|
GoalExpr0 = conj(ConjType, Goals0),
|
|
fill_conj_path_slots(RevPath0, 0, SlotInfo, Goals0, Goals),
|
|
GoalExpr = conj(ConjType, Goals)
|
|
;
|
|
GoalExpr0 = disj(Goals0),
|
|
fill_disj_path_slots(RevPath0, 0, SlotInfo, Goals0, Goals),
|
|
GoalExpr = disj(Goals)
|
|
;
|
|
GoalExpr0 = switch(Var, CanFail, Cases0),
|
|
VarTypes = SlotInfo ^ slot_info_vartypes,
|
|
ModuleInfo = SlotInfo ^ slot_info_module_info,
|
|
lookup_var_type(VarTypes, Var, Type),
|
|
( switch_type_num_functors(ModuleInfo, Type, NumFunctors) ->
|
|
MaybeNumFunctors = known_num_functors_in_type(NumFunctors)
|
|
;
|
|
MaybeNumFunctors = unknown_num_functors_in_type
|
|
),
|
|
fill_switch_path_slots(RevPath0, 0, MaybeNumFunctors, SlotInfo,
|
|
Cases0, Cases),
|
|
GoalExpr = switch(Var, CanFail, Cases)
|
|
;
|
|
GoalExpr0 = negation(SubGoal0),
|
|
RevPath = rgp_cons(RevPath0, step_neg),
|
|
fill_goal_path_slots(RevPath, SlotInfo, SubGoal0, SubGoal),
|
|
GoalExpr = negation(SubGoal)
|
|
;
|
|
GoalExpr0 = scope(Reason, SubGoal0),
|
|
% We should consider not filling in the goal path slots inside
|
|
% from_ground_term_construct scopes, since we do not use them
|
|
% for anything.
|
|
SubGoal0 = hlds_goal(_, InnerInfo),
|
|
OuterDetism = goal_info_get_determinism(GoalInfo),
|
|
InnerDetism = goal_info_get_determinism(InnerInfo),
|
|
( InnerDetism = OuterDetism ->
|
|
MaybeCut = scope_is_no_cut
|
|
;
|
|
MaybeCut = scope_is_cut
|
|
),
|
|
RevPath = rgp_cons(RevPath0, step_scope(MaybeCut)),
|
|
fill_goal_path_slots(RevPath, SlotInfo, SubGoal0, SubGoal),
|
|
GoalExpr = scope(Reason, SubGoal)
|
|
;
|
|
GoalExpr0 = if_then_else(Vars, Cond0, Then0, Else0),
|
|
RevPathCond = rgp_cons(RevPath0, step_ite_cond),
|
|
RevPathThen = rgp_cons(RevPath0, step_ite_then),
|
|
RevPathElse = rgp_cons(RevPath0, step_ite_else),
|
|
fill_goal_path_slots(RevPathCond, SlotInfo, Cond0, Cond),
|
|
fill_goal_path_slots(RevPathThen, SlotInfo, Then0, Then),
|
|
fill_goal_path_slots(RevPathElse, SlotInfo, Else0, Else),
|
|
GoalExpr = if_then_else(Vars, Cond, Then, Else)
|
|
;
|
|
GoalExpr0 = unify(LHS, RHS0, Mode, Kind, Context),
|
|
(
|
|
RHS0 = rhs_lambda_goal(Purity, Groundness, PredOrFunc, EvalMethod,
|
|
NonLocals, QuantVars, LambdaModes, Detism, LambdaGoal0),
|
|
fill_goal_path_slots(RevPath0, SlotInfo, LambdaGoal0, LambdaGoal),
|
|
RHS = rhs_lambda_goal(Purity, Groundness, PredOrFunc, EvalMethod,
|
|
NonLocals, QuantVars, LambdaModes, Detism, LambdaGoal)
|
|
;
|
|
( RHS0 = rhs_var(_)
|
|
; RHS0 = rhs_functor(_, _, _)
|
|
),
|
|
RHS = RHS0
|
|
),
|
|
GoalExpr = unify(LHS, RHS, Mode, Kind, Context)
|
|
;
|
|
( GoalExpr0 = plain_call(_, _, _, _, _, _)
|
|
; GoalExpr0 = generic_call(_, _, _, _, _)
|
|
; GoalExpr0 = call_foreign_proc(_, _, _, _, _, _, _)
|
|
),
|
|
GoalExpr = GoalExpr0
|
|
;
|
|
GoalExpr0 = shorthand(ShortHand0),
|
|
(
|
|
ShortHand0 = atomic_goal(GoalType, Outer, Inner, MaybeOutputVars,
|
|
MainGoal0, OrElseGoals0, OrElseInners),
|
|
RevPathMain = rgp_cons(RevPath0, step_atomic_main),
|
|
fill_goal_path_slots(RevPathMain, SlotInfo, MainGoal0, MainGoal),
|
|
fill_orelse_path_slots(RevPath0, 0, SlotInfo,
|
|
OrElseGoals0, OrElseGoals),
|
|
ShortHand = atomic_goal(GoalType, Outer, Inner, MaybeOutputVars,
|
|
MainGoal, OrElseGoals, OrElseInners)
|
|
;
|
|
ShortHand0 = try_goal(MaybeIO, ResultVar, SubGoal0),
|
|
RevPath = rgp_cons(RevPath0, step_try),
|
|
fill_goal_path_slots(RevPath, SlotInfo, SubGoal0, SubGoal),
|
|
ShortHand = try_goal(MaybeIO, ResultVar, SubGoal)
|
|
;
|
|
ShortHand0 = bi_implication(_, _),
|
|
% These should have been expanded out by now.
|
|
unexpected($module, $pred, "bi_implication")
|
|
),
|
|
GoalExpr = shorthand(ShortHand)
|
|
),
|
|
Goal = hlds_goal(GoalExpr, GoalInfo).
|
|
|
|
:- pred fill_conj_path_slots(reverse_goal_path::in, int::in, slot_info::in,
|
|
list(hlds_goal)::in, list(hlds_goal)::out) is det.
|
|
|
|
fill_conj_path_slots(_, _, _, [], []).
|
|
fill_conj_path_slots(RevPath0, N0, SlotInfo,
|
|
[Goal0 | Goals0], [Goal | Goals]) :-
|
|
N1 = N0 + 1,
|
|
fill_goal_path_slots(rgp_cons(RevPath0, step_conj(N1)), SlotInfo,
|
|
Goal0, Goal),
|
|
fill_conj_path_slots(RevPath0, N1, SlotInfo, Goals0, Goals).
|
|
|
|
:- pred fill_disj_path_slots(reverse_goal_path::in, int::in, slot_info::in,
|
|
list(hlds_goal)::in, list(hlds_goal)::out) is det.
|
|
|
|
fill_disj_path_slots(_, _, _, [], []).
|
|
fill_disj_path_slots(RevPath0, N0, SlotInfo,
|
|
[Goal0 | Goals0], [Goal | Goals]) :-
|
|
N1 = N0 + 1,
|
|
fill_goal_path_slots(rgp_cons(RevPath0, step_disj(N1)), SlotInfo,
|
|
Goal0, Goal),
|
|
fill_disj_path_slots(RevPath0, N1, SlotInfo, Goals0, Goals).
|
|
|
|
:- pred fill_switch_path_slots(reverse_goal_path::in,
|
|
int::in, maybe_switch_num_functors::in, slot_info::in,
|
|
list(case)::in, list(case)::out) is det.
|
|
|
|
fill_switch_path_slots(_, _, _, _, [], []).
|
|
fill_switch_path_slots(RevPath0, N0, MaybeNumFunctors, SlotInfo,
|
|
[Case0 | Cases0], [Case | Cases]) :-
|
|
Case0 = case(MainConsId, OtherConsIds, Goal0),
|
|
N1 = N0 + 1,
|
|
fill_goal_path_slots(rgp_cons(RevPath0, step_switch(N1, MaybeNumFunctors)),
|
|
SlotInfo, Goal0, Goal),
|
|
Case = case(MainConsId, OtherConsIds, Goal),
|
|
fill_switch_path_slots(RevPath0, N1, MaybeNumFunctors, SlotInfo,
|
|
Cases0, Cases).
|
|
|
|
:- pred fill_orelse_path_slots(reverse_goal_path::in, int::in,
|
|
slot_info::in, list(hlds_goal)::in, list(hlds_goal)::out) is det.
|
|
|
|
fill_orelse_path_slots(_, _, _, [], []).
|
|
fill_orelse_path_slots(RevPath0, N0, SlotInfo,
|
|
[Goal0 | Goals0], [Goal | Goals]) :-
|
|
N1 = N0 + 1,
|
|
fill_goal_path_slots(rgp_cons(RevPath0, step_atomic_orelse(N1)), SlotInfo,
|
|
Goal0, Goal),
|
|
fill_orelse_path_slots(RevPath0, N1, SlotInfo, Goals0, Goals).
|
|
|
|
%-----------------------------------------------------------------------------%
|
|
:- end_module hlds.goal_path.
|
|
%-----------------------------------------------------------------------------%
|