functional dependencies and overlapping instances

Peter Thiemann thiemann@informatik.uni-freiburg.de
31 Jan 2001 16:16:42 +0100


--=-=-=

Hi,

this reports two bugs in Hugs98-feb2000 and provides a fix for the
first and a proposed fix for the second.

1. Given the definitions

> class NextState s t s' | s t -> s'
> instance NextState EMPTY t EMPTY
> instance NextState EPSILON t EMPTY
> instance NextState (ATOM t) t EPSILON
> instance NextState (ATOM t) t' EMPTY

hugs -98 +o complains that 

ERROR "REGEXP.hs" (line 76): Instances are not consistent with dependencies
*** This instance    : NextState (ATOM a) b EMPTY
*** Conflicts with   : NextState EMPTY a EMPTY
*** For class        : NextState a b c
*** Under dependency : a b -> c

Oops, the "Conflicts with" line is not right, it should rather be

*** Conflicts with   : NextState (ATOM a) a EPSILON

The patch below corrects this.

2. But actually, since we are allowing overlapping instances and the
> instance NextState (ATOM t) t EPSILON
is definitely more specific than
> instance NextState (ATOM t) t' EMPTY
the above definitions should be perfectly ok.

The patch below fixes the generation of the error message, but other
fixes might be necessary, too.

Cheers
Peter

--=-=-=
Content-Type: text/x-patch
Content-Disposition: attachment; filename=static.patch
Content-Description: Patch for src/static.c

*** static.c.orig	Tue Feb 29 11:29:00 2000
--- static.c	Wed Jan 31 16:14:31 2001
***************
*** 2890,2906 ****
      if (nonNull(cclass(c).fds)) {	/* Check for conflicts with fds	   */
  	List ins1 = cclass(c).instances;
  	for (; nonNull(ins1); ins1=tl(ins1)) {
  	    List fds = cclass(c).fds;
  	    substitution(RESET);
  	    for (; nonNull(fds); fds=tl(fds)) {
  		Int  alpha = newKindedVars(inst(in).kinds);
! 		Int  beta  = newKindedVars(inst(hd(ins1)).kinds);
  		List as    = fst(hd(fds));
  		Bool same  = TRUE;
  		for (; same && nonNull(as); as=tl(as)) {
  		    Int n = offsetOf(hd(as));
  		    same &= unify(nthArg(n,inst(in).head),alpha,
! 				  nthArg(n,inst(hd(ins1)).head),beta);
  		}
  		if (isNull(as) && same) {
  		    for (as=snd(hd(fds)); same && nonNull(as); as=tl(as)) {
--- 2890,2921 ----
      if (nonNull(cclass(c).fds)) {	/* Check for conflicts with fds	   */
  	List ins1 = cclass(c).instances;
  	for (; nonNull(ins1); ins1=tl(ins1)) {
+ 	    Inst in1 = hd(ins1);
  	    List fds = cclass(c).fds;
  	    substitution(RESET);
  	    for (; nonNull(fds); fds=tl(fds)) {
  		Int  alpha = newKindedVars(inst(in).kinds);
! 		Int  beta  = newKindedVars(inst(in1).kinds);
  		List as    = fst(hd(fds));
  		Bool same  = TRUE;
+ 		/* <PJT> */ 
+ 		Int  alpha_bef = newKindedVars(inst(in).kinds);
+ 		Int  beta_bef  = newKindedVars(inst(in1).kinds);
+ 		Int  alpha_aft = newKindedVars(inst(in).kinds);
+ 		Int  beta_aft  = newKindedVars(inst(in1).kinds);
+ 		Bool bef   = TRUE;
+ 		Bool aft   = TRUE;
+ 		/* </PJT> */
  		for (; same && nonNull(as); as=tl(as)) {
  		    Int n = offsetOf(hd(as));
  		    same &= unify(nthArg(n,inst(in).head),alpha,
! 				  nthArg(n,inst(in1).head),beta);
! 		    /* <PJT> */
! 		    bef  &= matchType(nthArg(n,inst(in).head),alpha_bef,
! 				      nthArg(n,inst(in1).head),beta_bef);
! 		    aft  &= matchType(nthArg(n,inst(in1).head),beta_aft,
! 				      nthArg(n,inst(in).head),alpha_aft);
! 		    /* </PJT> */
  		}
  		if (isNull(as) && same) {
  		    for (as=snd(hd(fds)); same && nonNull(as); as=tl(as)) {
***************
*** 2908,2921 ****
  			same &= sameType(nthArg(n,inst(in).head),alpha,
  					 nthArg(n,inst(hd(ins1)).head),beta);
  		    }
! 		    if (!same) {
  			ERRMSG(inst(in).line)
  			   "Instances are not consistent with dependencies"
  			ETHEN
  			ERRTEXT "\n*** This instance    : "
  			ETHEN ERRPRED(inst(in).head);
  			ERRTEXT "\n*** Conflicts with   : "
! 			ETHEN ERRPRED(inst(hd(ins)).head);
  			ERRTEXT "\n*** For class        : "
  			ETHEN ERRPRED(cclass(c).head);
  			ERRTEXT "\n*** Under dependency : "
--- 2923,2941 ----
  			same &= sameType(nthArg(n,inst(in).head),alpha,
  					 nthArg(n,inst(hd(ins1)).head),beta);
  		    }
! 		    if (!same
! 		        /* <PJT> */
! 			&& !(allowOverlap && !haskell98
! 			     && (bef && !aft || aft && !bef))
! 			/* </PJT> */
! 			) {
  			ERRMSG(inst(in).line)
  			   "Instances are not consistent with dependencies"
  			ETHEN
  			ERRTEXT "\n*** This instance    : "
  			ETHEN ERRPRED(inst(in).head);
  			ERRTEXT "\n*** Conflicts with   : "
! 			ETHEN ERRPRED(inst(in1).head);
  			ERRTEXT "\n*** For class        : "
  			ETHEN ERRPRED(cclass(c).head);
  			ERRTEXT "\n*** Under dependency : "

--=-=-=--