[m-dev.] for review: handle non-simple typeclass constraints
Fergus Henderson
fjh at cs.mu.OZ.AU
Thu Apr 9 00:56:38 AEST 1998
On 08-Apr-1998, Fergus Henderson <fjh at cs.mu.OZ.AU> wrote:
> [Another diff will follow.]
... and here it is. This diff is relative to the previous one.
As well as addressing DJ's comments, I fixed a bug:
my previous changes broke apply_class_rules.
The log message is as before except for check_typeclass.m.
compiler/check_typeclass.m:
Change the way we superclass conformance for instance
declarations to take advantage of the new "DeclaredConstraints"
argument to typecheck__reduce_context_by_rule_application.
--- old/check_typeclass.m Thu Apr 9 00:05:41 1998
+++ check_typeclass.m Thu Apr 9 00:31:18 1998
@@ -413,6 +413,9 @@
%---------------------------------------------------------------------------%
+% check that the superclass constraints are satisfied for the
+% types in this instance declaration
+
:- pred check_superclass_conformance(list(class_constraint), list(var),
varset, module_info, hlds_instance_defn, hlds_instance_defn,
list(string), list(string)).
@@ -446,43 +449,18 @@
module_info_classes(ModuleInfo, ClassTable),
(
- % Reduce the superclass constraints
+ % Try to reduce the superclass constraints,
+ % using the declared instance constraints
+ % and the usual context reduction rules.
typecheck__reduce_context_by_rule_application(InstanceTable,
- ClassTable, [], TypeSubst,
+ ClassTable, InstanceConstraints, TypeSubst,
InstanceVarSet1, InstanceVarSet2,
Proofs0, Proofs1, SuperClasses,
- ReducedSuperClasses0),
-
- % Reduce the constraints from the instance declaration
- typecheck__reduce_context_by_rule_application(InstanceTable,
- ClassTable, [], TypeSubst,
- InstanceVarSet2, InstanceVarSet2,
- Proofs1, Proofs2, InstanceConstraints,
- ReducedInstanceConstraints0)
- ->
- ReducedSuperClasses0 = ReducedSuperClasses,
- ReducedInstanceConstraints = ReducedInstanceConstraints0,
- Proofs = Proofs2,
- InstanceVarSet = InstanceVarSet2
- ;
- % This should never happen, since the superclass and
- % instance constraints must all contain only variables.
- % Context reduction can only fail if there is a
- % constraint with a type with a bound top-level functor
- % for which there is no instance decl.
- error("check_superclass_conformance: context reduction failed")
- ),
-
- % Check for superclass constraints that are unsatisfied by
- % the instance declaration
- list__delete_elems(ReducedSuperClasses, ReducedInstanceConstraints,
- Unsatisfied),
- (
- Unsatisfied = []
+ [])
->
Errors = Errors0,
InstanceDefn = hlds_instance_defn(A, InstanceConstraints,
- InstanceTypes, D, E, InstanceVarSet, Proofs)
+ InstanceTypes, D, E, InstanceVarSet2, Proofs1)
;
% XXX improve the error message
NewError = "superclass constraint unsatisfied",
@@ -491,4 +469,3 @@
).
%---------------------------------------------------------------------------%
-
--- old/typecheck.m Thu Apr 9 00:05:50 1998
+++ typecheck.m Thu Apr 9 00:19:01 1998
@@ -978,7 +978,7 @@
% Arguably, we could do context reduction at
% a different point. See the paper:
% "Type classes: an exploration of the design
- % space", S.P. Jones, M. Jones 1997.
+ % space", S. Peyton-Jones, M. Jones 1997.
% for a discussion of some of the issues.
perform_context_reduction(OrigTypeAssignSet, TypeCheckInfo2,
TypeCheckInfo)
@@ -3009,7 +3009,7 @@
% context reduction on the type_assigns in TypeCheckInfo0,
% or, if there is no valid context reduction, then
% TypeCheckInfo is TypeCheckInfo0 with the type assign set replaced by
-% OrigTypeAssignSet.
+% OrigTypeAssignSet (see below).
%
% Context reduction is the process of eliminating redundant constraints
% from the constraints in the type_assign and adding the proof of the
@@ -3017,6 +3017,8 @@
% are three ways in which a constraint may be redundant:
% - if a constraint occurs in the pred/func declaration for this
% predicate or function, then it is redundant
+% (in this case, the proof is trivial, so there is no need
+% to record it in the proof map)
% - if a constraint is present in the set of constraints and all
% of the "superclass" constraints for the constraints are all
% present, then all the superclass constraints are eliminated
@@ -3034,9 +3036,9 @@
%
% If all type_assigns from the typecheck_info are rejected, than an
% appropriate error message is given, and the type_assign_set is
-% restored to the original one given by OrigTypeAssignSet
-% (this is to avoid reporting the same error at every subsequent call
-% to perform_context_reduction).
+% restored to the original one given by OrigTypeAssignSet.
+% The reason for this is to avoid reporting the same error at
+% every subsequent call to perform_context_reduction.
:- pred perform_context_reduction(type_assign_set,
typecheck_info, typecheck_info).
@@ -3095,8 +3097,8 @@
apply_rec_subst_to_constraints(Bindings, Constraints0, Constraints1),
eliminate_declared_constraints(Constraints1, DeclaredConstraints,
Constraints2, Changed1),
- apply_class_rules(Constraints2, ClassTable, Tvarset0,
- Proofs0, Proofs1, Constraints3, Changed2),
+ apply_class_rules(Constraints2, DeclaredConstraints, ClassTable,
+ Tvarset0, Proofs0, Proofs1, Constraints3, Changed2),
apply_instance_rules(Constraints3, InstanceTable,
Tvarset0, Tvarset1, Proofs1, Proofs2, Constraints4, Changed3),
(
@@ -3238,19 +3240,21 @@
Proofs, NewConstraints)
).
- % To reduce the context using class declarations, we scan the
- % context one constraint at a time. For each class in the constraint,
- % we check to see if any of its superclasses is also a constraint, and
- % if so, delete the superclass from the constraint list as it is
- % redundant.
-:- pred apply_class_rules(list(class_constraint), class_table,
- tvarset, map(class_constraint, constraint_proof),
+ % To reduce the context using class declarations, we scan the
+ % declared contexts plus the current inferred context one
+ % constraint at a time. For each such class constraint, we
+ % check to see if any of its superclasses is also a constraint,
+ % and if so, delete the superclass from the current constraint
+ % list as it is redundant.
+:- pred apply_class_rules(list(class_constraint), list(class_constraint),
+ class_table, tvarset, map(class_constraint, constraint_proof),
map(class_constraint, constraint_proof), list(class_constraint), bool).
-:- mode apply_class_rules(in, in, in, in, out, out, out) is det.
+:- mode apply_class_rules(in, in, in, in, in, out, out, out) is det.
-apply_class_rules(Constraints0, ClassTable, TVarSet,
+apply_class_rules(Constraints0, DeclaredConstraints, ClassTable, TVarSet,
Proofs0, Proofs, Constraints, Changed) :-
- apply_class_rules_2(Constraints0, Constraints0, ClassTable,
+ list__append(DeclaredConstraints, Constraints0, AllConstraints),
+ apply_class_rules_2(AllConstraints, Constraints0, ClassTable,
TVarSet, Proofs0, Proofs, Constraints, Changed).
:- pred apply_class_rules_2(list(class_constraint), list(class_constraint),
@@ -3258,12 +3262,13 @@
map(class_constraint, constraint_proof), list(class_constraint), bool).
:- mode apply_class_rules_2(in, in, in, in, in, out, out, out) is det.
- % The first argument is the list of constraints left to be checked.
- % The second argument is the list of constraints that have not been
- % rejected. If a redundant constraint is found, it is deleted from
- % both (if it is still in the first list).
+ % The first argument is the list of declared or inferred constraints
+ % left to be checked.
+ % The second argument is the list of currently inferred constraints
+ % that have not been rejected. If a redundant constraint is found,
+ % it is deleted from both (if it is still in the first list).
apply_class_rules_2([], Constraints, _, _, Proofs, Proofs, Constraints, no).
-apply_class_rules_2([C|Cs], AllConstraints, ClassTable, TVarSet,
+apply_class_rules_2([C|Cs], Constraints0, ClassTable, TVarSet,
Proofs0, Proofs, Constraints, Changed) :-
C = constraint(ClassName, Types),
list__length(Types, Arity),
@@ -3283,14 +3288,13 @@
type_list_subsumes(NewClassTypes, Types, Subst),
apply_rec_subst_to_constraint(Subst, ThisConstraint,
RenamedConstraint),
- list__member(RenamedConstraint, AllConstraints)
+ list__member(RenamedConstraint, Constraints0)
)),
list__filter_map(IsRedundant, ParentClassConstraints,
RedundantConstraints),
% Delete the redundant constraints
- list__delete_elems(AllConstraints, RedundantConstraints,
- NewConstraints),
+ list__delete_elems(Constraints0, RedundantConstraints, Constraints1),
list__delete_elems(Cs, RedundantConstraints, NewCs),
% Remember why the constraints were redundant
@@ -3309,7 +3313,7 @@
Changed1 = yes
),
- apply_class_rules_2(NewCs, NewConstraints, ClassTable,
+ apply_class_rules_2(NewCs, Constraints1, ClassTable,
NewTVarSet, Proofs1, Proofs, Constraints, Changed2),
bool__or(Changed1, Changed2, Changed).
--
Fergus Henderson <fjh at cs.mu.oz.au> | "I have always known that the pursuit
WWW: <http://www.cs.mu.oz.au/~fjh> | of excellence is a lethal habit"
PGP: finger fjh at 128.250.37.3 | -- the last words of T. S. Garp.
More information about the developers
mailing list