Don't push constraints into scopes where they could change the meaning

Estimated hours taken: 0.5
Branches: main, release

compiler/constraint.m:
	Don't push constraints into scopes where they could change the meaning
	of the scope.

	Turn the predicate into a single disjunction to make the head variables
	meaningful (and consistent) names in the debugger.

tests/Mmakefile:
	Compile the one_member test case with -O5, since the old bug in
	constraint.m doesn't manifest itself at the default optimization level.
This commit is contained in:
Zoltan Somogyi
2006-04-07 01:29:28 +00:00
parent 61c7f4ed4e
commit c5af97ea18
2 changed files with 78 additions and 71 deletions

View File

@@ -127,81 +127,87 @@ propagate_conj_sub_goal(Goal0, Constraints, Goals, !Info, !IO) :-
list(hlds_goal)::out, constraint_info::in, constraint_info::out,
io::di, io::uo) is det.
propagate_conj_sub_goal_2(conj(ConjType, Goals0) - GoalInfo, Constraints0,
[conj(ConjType, Goals) - GoalInfo | MoreGoals], !Info, !IO) :-
propagate_conj_sub_goal_2(GoalExpr - GoalInfo, Constraints, FinalGoals, !Info,
!IO) :-
(
ConjType = plain_conj,
MoreGoals = [],
propagate_conj(Goals0, Constraints0, Goals, !Info, !IO)
GoalExpr = conj(ConjType, Goals0),
(
ConjType = plain_conj,
propagate_conj(Goals0, Constraints, Goals, !Info, !IO),
FinalGoals = [conj(ConjType, Goals) - GoalInfo]
;
ConjType = parallel_conj,
% We can't propagate constraints into parallel conjunctions because
% parallel conjunctions must have determinism det. However, we can
% propagate constraints *within* the goals of the conjunction.
flatten_constraints(Constraints, MoreGoals),
propagate_in_independent_goals(Goals0, [], Goals, !Info, !IO),
FinalGoals = [conj(ConjType, Goals) - GoalInfo | MoreGoals]
)
;
ConjType = parallel_conj,
% We can't propagate constraints into parallel conjunctions because
% parallel conjunctions must have determinism det. However, we can
% propagate constraints *within* the goals of the conjunction.
flatten_constraints(Constraints0, MoreGoals),
propagate_in_independent_goals(Goals0, [], Goals, !Info, !IO)
GoalExpr = disj(Goals0),
propagate_in_independent_goals(Goals0, Constraints, Goals, !Info, !IO),
FinalGoals = [disj(Goals) - GoalInfo]
;
GoalExpr = switch(Var, CanFail, Cases0),
propagate_cases(Var, Constraints, Cases0, Cases, !Info, !IO),
FinalGoals = [switch(Var, CanFail, Cases) - GoalInfo]
;
GoalExpr = if_then_else(Vars, Cond0, Then0, Else0),
InstMap0 = !.Info ^ instmap,
% We can't safely propagate constraints into the condition of an
% if-then-else, because that would change the answers generated
% by the procedure.
propagate_goal(Cond0, [], Cond, !Info, !IO),
constraint_info_update_goal(Cond, !Info),
propagate_goal(Then0, Constraints, Then, !Info, !IO),
!:Info = !.Info ^ instmap := InstMap0,
propagate_goal(Else0, Constraints, Else, !Info, !IO),
FinalGoals = [if_then_else(Vars, Cond, Then, Else) - GoalInfo]
;
GoalExpr = scope(Reason, SubGoal0),
(
Reason = exist_quant(_),
propagate_goal(SubGoal0, Constraints, SubGoal, !Info, !IO),
FinalGoals = [scope(Reason, SubGoal) - GoalInfo]
;
Reason = from_ground_term(_),
propagate_goal(SubGoal0, Constraints, SubGoal, !Info, !IO),
FinalGoals = [scope(Reason, SubGoal) - GoalInfo]
;
( Reason = promise_solutions(_, _)
; Reason = promise_purity(_, _)
; Reason = commit(_)
; Reason = barrier(_)
),
% We can't safely propagate constraints into one of these scopes.
% However, we can propagate constraints inside the scope goal.
propagate_goal(SubGoal0, [], SubGoal, !Info, !IO),
flatten_constraints(Constraints, ConstraintGoals),
FinalGoals = [scope(Reason, SubGoal) - GoalInfo | ConstraintGoals]
)
;
GoalExpr = not(NegGoal0),
% We can't safely propagate constraints into a negation,
% because that would change the answers computed by the procedure.
propagate_goal(NegGoal0, [], NegGoal, !Info, !IO),
flatten_constraints(Constraints, ConstraintGoals),
FinalGoals = [not(NegGoal) - GoalInfo | ConstraintGoals]
;
( GoalExpr = call(_, _, _, _, _, _)
; GoalExpr = generic_call(_, _, _, _)
; GoalExpr = foreign_proc(_, _, _, _, _, _)
; GoalExpr = unify(_, _, _, _, _)
),
% Propagate_conj will move the constraints to the left of the call
% or unification if that is possible, so nothing needs to be done here.
flatten_constraints(Constraints, ConstraintGoals),
FinalGoals = [GoalExpr - GoalInfo | ConstraintGoals]
;
GoalExpr = shorthand(_),
unexpected(this_file, "propagate_conj_sub_goal_2: shorthand")
).
propagate_conj_sub_goal_2(disj(Goals0) - Info, Constraints,
[disj(Goals) - Info], !Info, !IO) :-
propagate_in_independent_goals(Goals0, Constraints, Goals, !Info, !IO).
propagate_conj_sub_goal_2(switch(Var, CanFail, Cases0) - Info,
Constraints, [switch(Var, CanFail, Cases) - Info], !Info, !IO) :-
propagate_cases(Var, Constraints, Cases0, Cases, !Info, !IO).
propagate_conj_sub_goal_2(
if_then_else(Vars, Cond0, Then0, Else0) - Info,
Constraints,
[if_then_else(Vars, Cond, Then, Else) - Info], !Info, !IO) :-
InstMap0 = !.Info ^ instmap,
% We can't safely propagate constraints into the condition of an
% if-then-else, because that would change the answers generated
% by the procedure.
propagate_goal(Cond0, [], Cond, !Info, !IO),
constraint_info_update_goal(Cond, !Info),
propagate_goal(Then0, Constraints, Then, !Info, !IO),
!:Info = !.Info ^ instmap := InstMap0,
propagate_goal(Else0, Constraints, Else, !Info, !IO).
propagate_conj_sub_goal_2(scope(Reason, Goal0) - GoalInfo, Constraints,
[scope(Reason, Goal) - GoalInfo], !Info, !IO) :-
propagate_goal(Goal0, Constraints, Goal, !Info, !IO).
propagate_conj_sub_goal_2(not(NegGoal0) - GoalInfo, Constraints0,
[not(NegGoal) - GoalInfo | Constraints], !Info, !IO) :-
% We can't safely propagate constraints into a negation,
% because that would change the answers computed by the procedure.
propagate_goal(NegGoal0, [], NegGoal, !Info, !IO),
flatten_constraints(Constraints0, Constraints).
propagate_conj_sub_goal_2(Goal, Constraints0,
[Goal | Constraints], !Info, !IO) :-
% Propagate_conj will move the constraints to the left of the call
% if that is possible, so nothing needs to be done here.
Goal = call(_, _, _, _, _, _) - _,
flatten_constraints(Constraints0, Constraints).
propagate_conj_sub_goal_2(Goal, Constraints0,
[Goal | Constraints], !Info, !IO) :-
Goal = generic_call(_, _, _, _) - _,
flatten_constraints(Constraints0, Constraints).
propagate_conj_sub_goal_2(Goal, Constraints0,
[Goal | Constraints], !Info, !IO) :-
Goal = foreign_proc(_, _, _, _, _, _) - _,
flatten_constraints(Constraints0, Constraints).
propagate_conj_sub_goal_2(Goal, Constraints0,
[Goal | Constraints], !Info, !IO) :-
Goal = unify(_, _, _, _, _) - _,
flatten_constraints(Constraints0, Constraints).
propagate_conj_sub_goal_2(Goal, _, _, !Info, !IO) :-
Goal = shorthand(_) - _,
unexpected(this_file, "propagate_conj_sub_goal_2: shorthand").
%-----------------------------------------------------------------------------%
% Put the constant constructions in front of the constraint.

View File

@@ -12,6 +12,7 @@ MCFLAGS-func_test = --infer-all
MCFLAGS-ho_order = --optimize-higher-order
MCFLAGS-ho_order2 = --optimize-higher-order
MCFLAGS-no_fully_strict = --no-fully-strict
MCFLAGS-one_member = -O5
MCFLAGS-impure_foreign = --optimize-duplicate-calls
MCFLAGS-intermod_c_code = --intermodule-optimization
MCFLAGS-intermod_c_code2 = --intermodule-optimization