1 /* -*- mode: hugs-c; -*- */
2 /* --------------------------------------------------------------------------
3 * preds.c: Copyright (c) Mark P Jones 1991-1998. All rights reserved.
4 * See NOTICE for details and conditions of use etc...
5 * Hugs version 1.3c, March 1998
7 * Part of type checker dealing with predicates and entailment.
8 * ------------------------------------------------------------------------*/
10 /* --------------------------------------------------------------------------
11 * Local function prototypes:
12 * ------------------------------------------------------------------------*/
14 static Cell local assumeEvid Args((Cell,Int));
15 static List local makePredAss Args((List,Int));
16 static List local copyPreds Args((List));
17 static Void local qualify Args((List,Cell));
18 static Void local qualifyBinding Args((List,Cell));
19 static Cell local qualifyExpr Args((Int,List,Cell));
20 static Void local overEvid Args((Cell,Cell));
22 static Cell local scFind Args((Cell,Cell,Int,Cell,Int));
23 static Cell local scEntail Args((List,Cell,Int));
24 static Cell local entail Args((List,Cell,Int));
25 static Cell local inEntail Args((List,Cell,Int));
27 static Cell local lacksNorm Args((Type,Int,Cell));
30 static List local scSimplify Args((List));
31 static Void local elimTauts Args((Void));
32 static Bool local anyGenerics Args((Type,Int));
33 static List local elimOuterPreds Args((List));
34 static List local elimPredsUsing Args((List,List));
35 static Void local reducePreds Args((Void));
36 static Void local normPreds Args((Int));
38 static Bool local resolveDefs Args((List));
39 static Bool local resolveVar Args((Int));
40 static Class local classConstraining Args((Int,Cell,Int));
42 /* --------------------------------------------------------------------------
43 * Predicate assignments:
45 * A predicate assignment is represented by a list of triples (pi,o,ev)
46 * where o is the offset for types in pi, with evidence required at the
47 * node pointed to by ev (which is taken as a dictionary parameter if
48 * no other evidence is available). Note that the ev node will be
49 * overwritten at a later stage if evidence for that predicate is found
51 * ------------------------------------------------------------------------*/
53 static List preds; /* Current predicate assignment */
55 static Cell local assumeEvid(pi,o) /* Add predicate pi (offset o) to */
56 Cell pi; /* preds with new dict var nd */
58 Cell nd = inventDictVar();
59 preds = cons(triple(pi,mkInt(o),nd),preds);
63 static List local makePredAss(qs,o) /* Make list of predicate assumps. */
64 List qs; /* from qs (offset o), w/ new dict */
65 Int o; { /* vars for each predicate */
67 for (; nonNull(qs); qs=tl(qs))
68 result = cons(triple(hd(qs),mkInt(o),inventDictVar()),result);
72 static List local copyPreds(qs) /* Copy list of predicates */
75 for (; nonNull(qs); qs=tl(qs)) {
77 result = cons(copyPred(fst3(pi),intOf(snd3(pi))),result);
82 static Void local qualify(qs,alt) /* Add extra dictionary args to */
83 List qs; /* qualify alt by predicates in qs */
84 Cell alt; { /* :: ([Pat],Rhs) */
86 for (ds=NIL; nonNull(qs); qs=tl(qs))
87 ds = cons(thd3(hd(qs)),ds);
88 fst(alt) = revOnto(ds,fst(alt));
91 static Void local qualifyBinding(qs,b) /* Add extra dict args to each */
92 List qs; /* alternative in function binding */
94 if (!isVar(fst(b))) /* check for function binding */
95 internal("qualifyBinding");
96 map1Proc(qualify,qs,snd(snd(b)));
99 static Cell local qualifyExpr(l,ps,e) /* Add dictionary params to expr */
103 if (nonNull(ps)) { /* Qualify input expression with */
104 if (whatIs(e)!=LAMBDA) /* additional dictionary params */
105 e = ap(LAMBDA,pair(NIL,pair(mkInt(l),e)));
111 static Void local overEvid(dv,ev) /* Overwrite dict var dv with */
112 Cell dv; /* evidence ev */
118 /* --------------------------------------------------------------------------
119 * Predicate entailment:
121 * Entailment plays a prominent role in the theory of qualified types, and
122 * so, unsurprisingly, in the implementation too. For practical reasons,
123 * we break down entailment into two pieces. The first, scEntail, uses
124 * only the information provided by class declarations, while the second,
125 * entail, also uses the information in instance declarations.
127 * scEntail uses the following auxiliary function to do its work:
129 * scFind (e : pi') pi : Find evidence for predicate pi using only
130 * equality of predicates, superclass entailment,
131 * and the evidence e for pi'.
133 * scFind (e : pi') pi =
138 * if (pi.class.level < pi'.class.level)
139 * get superclass entailment pi' ||- P
140 * for each (sc, pi0) in P
141 * if (ev := scFind (sc e : pi0) pi) /= NIL
146 * This code assumes that the class hierarchy is acyclic, and that
147 * each class has been assigned a `level', which is its height in
148 * the hierachy. The first of the assumptions guarantees that the
149 * algorithm will terminate. The comparison of levels is an
150 * optimization that cuts down the search space: given that superclass
151 * entailments can only be used to descend the hierarchy, there is no
152 * way we can reach a higher level than the one that we start with,
153 * and hence there is no point in looking if we reach such a position.
155 * scEntail extends scFind to work on whole predicate assignments:
157 * scEntail P pi : Find evidence for predicate pi using the evidence
158 * provided by the predicate assignment P, and using
159 * only superclass entailments.
163 * for each (v:pi') in P
164 * if (ev := scFind (v:pi') pi) /= NIL
168 * ------------------------------------------------------------------------*/
170 static Cell local scFind(e,pi1,o1,pi,o) /* Use superclass entailment to */
171 Cell e; /* find evidence for (pi,o) using */
172 Cell pi1; /* the evidence e for (pi1,o1). */
176 Class h1 = getHead(pi1);
177 Class h = getHead(pi);
179 if (h==h1 && samePred(pi1,o1,pi,o))
182 if (isClass(h1) && (!isClass(h) || cclass(h).level<cclass(h1).level)) {
183 Int beta = newKindedVars(cclass(h1).kinds);
184 List scs = cclass(h1).supers;
185 List dsels = cclass(h1).dsels;
186 if (!matchPred(pi1,o1,cclass(h1).head,beta))
188 for (; nonNull(scs); scs=tl(scs), dsels=tl(dsels)) {
189 Cell ev = scFind(ap(hd(dsels),e),hd(scs),beta,pi,o);
198 static Cell local scEntail(ps,pi,o) /* Calc evidence for (pi,o) from ps*/
199 List ps; /* Using superclasses and equality.*/
202 for (; nonNull(ps); ps=tl(ps)) {
204 Cell ev = scFind(thd3(pi1),fst3(pi1),intOf(snd3(pi1)),pi,o);
211 /* --------------------------------------------------------------------------
212 * Now we reach the main entailment routine:
214 * entail P pi : Find evidence for predicate pi using the evidence
215 * provided by the predicate assignment P.
219 * if (ev := scEntail P pi) /= NIL
222 * if there is an instance entailment i : Q ||- pi
224 * if (ev := entail P pi') /= NIL
232 * The form of evidence expressions produced by scEntail can be described
235 * e = v | sc e (v = evidence var, sc = superclass sel)
237 * while entail extends this to include dictionary expressions given by:
239 * d = e | mki d1 ... dn (mki = dictionary constructor)
241 * A full grammar for evidence expressions is:
243 * d = v | sc d | mki d1 ... dn
245 * and this includes evidence expressions of the form sc (mki d1 ... dn)
246 * that can never be produced by either of the entail functions described
247 * above. This is good, from a practical perspective, because t means
248 * that we won't waste effort building a dictionary (mki d1 ... dn) only
249 * to extract just one superclass component and throw the rest away.
250 * Moreover, conditions on instance decls already guarantee that any
251 * expression of this form can be rewritten in the form mki' d1' ... dn'.
252 * (Minor point: they don't guarantee that such rewritings will lead to
253 * smaller terms, and hence to termination. However, we have already
254 * accepted the benefits of an undecidable entailment relation over
255 * guarantees of termination, and this additional quirk is unlikely
256 * to cause any further concern, except in pathological cases.)
257 * ------------------------------------------------------------------------*/
259 static Cell local entail(ps,pi,o) /* Calc evidence for (pi,o) from ps*/
260 List ps; /* Uses superclasses, equality, */
261 Cell pi; /* tautology, and construction */
263 Cell ev = scEntail(ps,pi,o);
264 return nonNull(ev) ? ev : inEntail(ps,pi,o);
267 static Cell local inEntail(ps,pi,o) /* Calc evidence for (pi,o) from ps*/
268 List ps; /* using a top-level instance */
269 Cell pi; /* entailment */
272 if (isAp(pi) && isExt(fun(pi))) { /* Lacks predicates */
275 l = lacksNorm(arg(pi),o,e);
276 if (isNull(l) || isInt(l))
280 for (; nonNull(qs); qs=tl(qs)) {
281 Cell qi = fst3(hd(qs));
282 if (isAp(qi) && fun(qi)==e) {
283 Cell lq = lacksNorm(arg(qi),intOf(snd3(hd(qs))),e);
284 if (isAp(lq) && intOf(fst(l))==intOf(fst(lq))) {
285 Int f = intOf(snd(l)) - intOf(snd(lq));
286 return (f==0) ? thd3(hd(qs)) : ap2(nameAddEv,
297 Inst in = findInstFor(pi,o); /* Class predicates */
300 Cell d = inst(in).builder;
301 Cell ds = inst(in).specifics;
302 for (; nonNull(ds); ds=tl(ds)) {
303 Cell ev = entail(ps,hd(ds),beta);
317 Cell provePred(ks,ps,pi) /* Find evidence for predicate pi */
318 Kinds ks; /* assuming ps. If ps is null, */
319 List ps; /* then we get to decide whether */
320 Cell pi; { /* is tautological, and we can use */
321 Int beta; /* the evidence as a dictionary. */
324 beta = newKindedVars(ks); /* (ks provides kinds for any */
325 ps = makePredAss(ps,beta); /* vars that appear in pi.) */
326 ev = entail(ps,pi,beta);
332 static Cell local lacksNorm(t,o,e) /* Normalize lacks pred (t,o)\l */
333 Type t; /* returning NIL (unsatisfiable), */
334 Int o; /* Int (tautological) or pair (v,a)*/
335 Cell e; { /* such that, if e is evid for v\l,*/
336 Text l = extText(e); /* then (e+a) is evid for (t,o)\l. */
342 return pair(mkInt(tyvNum(tyv)),mkInt(a));
344 Cell h = getDerefHead(t,o);
345 if (h==typeNoRow && argCount==0)
347 else if (isExt(h) && argCount==2) {
348 Text l1 = extText(h);
351 else if (strcmp(textToStr(l1),textToStr(l))<0)
362 /* --------------------------------------------------------------------------
363 * Predicate set Simplification:
365 * Calculate a minimal equivalent subset of a given set of predicates.
366 * ------------------------------------------------------------------------*/
368 static List local scSimplify(qs) /* Simplify predicates in qs, */
369 List qs; { /* returning equiv minimal subset */
374 Cell ev = scEntail(tl(qs),fst3(pi),intOf(snd3(pi)));
376 overEvid(thd3(pi),ev); /* Overwrite dict var with evidence*/
377 qs = tl(qs); /* ... and discard predicate */
379 else { /* Otherwise, retain predicate */
382 qs = appendOnto(tmp,qs);
388 List simpleContext(ps,o) /* Simplify context of skeletons */
389 List ps; /* skeletons, offset o, using */
390 Int o; { /* superclass hierarchy */
391 return copyPreds(scSimplify(makePredAss(ps,o)));
394 /* --------------------------------------------------------------------------
395 * Context splitting --- tautological and locally tautological predicates:
396 * ------------------------------------------------------------------------*/
398 static Void local elimTauts() { /* Remove tautological constraints */
399 List ps = preds; /* from preds */
401 while (nonNull(ps)) {
403 Cell ev = entail(NIL,fst3(pi),intOf(snd3(pi)));
405 overEvid(thd3(pi),ev);
417 static Int numFixedVars = 0; /* Number of fixed vars found */
419 static Bool local anyGenerics(t,o) /* Test for generic vars, and count*/
420 Type t; /* fixed variables */
422 Type h = getDerefHead(t,o); /* This code is careful to expand */
423 Int a = argCount; /* synonyms; mark* & copy* do not. */
424 if (isSynonym(h) && a>=tycon(h).arity) {
425 expandSyn(h,a,&t,&o);
426 return anyGenerics(t,o);
430 for (; 0<a--; t=fun(t)) { /* cycle through any arguments */
432 if (anyGenerics(arg(t),o))
437 if (tyv->offs == FIXED_TYVAR) {
448 static List local elimOuterPreds(sps) /* Simplify and defer any remaining*/
449 List sps; { /* preds that contain no generics. */
452 for (preds=scSimplify(preds); nonNull(preds); ) {
455 if (anyGenerics(fst3(pi),intOf(snd3(pi)))) { /* Retain predicate*/
459 else { /* Defer predicate */
469 static List local elimPredsUsing(ps,sps)/* Try to discharge or defer preds,*/
470 List ps; /* splitting if necessary to match */
471 List sps; { /* context ps. sps = savePreds. */
473 while (nonNull(preds)) { /* Pick a predicate from preds */
475 Cell pi = fst3(hd(p));
476 Int o = intOf(snd3(hd(p)));
477 Cell ev = entail(ps,pi,o);
480 if (nonNull(ev)) /* Discharge if ps ||- (pi,o) */
481 overEvid(thd3(hd(p)),ev);
482 else if (!anyGenerics(pi,o)) { /* Defer if no generics */
486 else { /* Try to split generics and fixed */
488 if (numFixedVars>0 && nonNull(in=findInstFor(pi,o))) {
489 List qs = inst(in).specifics;
490 for (ev=inst(in).builder; nonNull(qs); qs=tl(qs))
491 ev = ap(ev,assumeEvid(hd(qs),typeOff));
492 overEvid(thd3(hd(p)),ev);
494 else { /* No worthwhile progress possible */
500 preds = rems; /* Return any remaining predicates */
504 static Void local reducePreds() { /* Context reduce predicates: uggh!*/
505 List rems = NIL; /* (A last resort for defaulting) */
506 while (nonNull(preds)) { /* Pick a predicate from preds */
508 Cell pi = fst3(hd(p));
509 Int o = intOf(snd3(hd(p)));
510 Inst in = findInstFor(pi,o);
513 List qs = inst(in).specifics;
514 Cell ev = inst(in).builder;
515 for (; nonNull(qs); qs=tl(qs))
516 ev = ap(ev,assumeEvid(hd(qs),typeOff));
517 overEvid(thd3(hd(p)),ev);
519 else { /* No worthwhile progress possible */
524 preds = scSimplify(rems); /* Return any remaining predicates */
527 static Void local normPreds(line) /* Normalize each element of preds */
528 Int line; { /* in some appropriate manner */
532 while (nonNull(ps)) {
533 Cell pi = fst3(hd(ps));
534 Cell ev = thd3(hd(ps));
535 if (isAp(pi) && isExt(fun(pi))) {
536 Cell r = lacksNorm(arg(pi),intOf(snd3(hd(ps))),fun(pi));
538 ERRMSG(line) "Cannot satisfy constraint " ETHEN
539 ERRPRED(copyPred(pi,intOf(snd3(hd(ps)))));
551 else if (intOf(snd(r))!=0) {
552 Cell nd = inventDictVar();
553 Cell ev1 = ap2(nameAddEv,snd(r),nd);
554 pi = ap(fun(pi),aVar);
555 hd(ps) = triple(pi,fst(r),nd);
561 fst3(hd(ps)) = ap(fun(pi),fst(r));
574 /* --------------------------------------------------------------------------
575 * Mechanisms for dealing with defaults:
576 * ------------------------------------------------------------------------*/
578 static Bool local resolveDefs(vs) /* Attempt to resolve defaults */
579 List vs; { /* for variables vs subject to */
580 List pvs = NIL; /* constraints in preds */
582 Bool defaulted = FALSE;
584 #ifdef DEBUG_DEFAULTS
585 printf("Attempt to resolve variables ");
587 printf(" with context ");
588 printContext(stdout,copyPreds(preds));
592 resetGenerics(); /* find type variables in ps */
593 for (; nonNull(qs); qs=tl(qs)) {
594 Cell pi = fst3(hd(qs));
595 Int o = intOf(snd3(hd(qs)));
596 for (; isAp(pi); pi=fun(pi))
597 pvs = genvarType(arg(pi),o,pvs);
600 for (; nonNull(pvs); pvs=tl(pvs)) { /* now try defaults */
601 Int vn = intOf(hd(pvs));
603 #ifdef DEBUG_DEFAULTS
604 printf("is var %d included in ",vn);
609 if (!intIsMember(vn,vs))
610 defaulted |= resolveVar(vn);
611 #ifdef DEBUG_DEFAULTS
613 printf("Yes, so no ambiguity!\n");
620 static Bool local resolveVar(vn) /* Determine whether an ambig. */
621 Int vn; { /* variable vn can be resolved */
622 List ps = preds; /* by default in the context of */
623 List cs = NIL; /* the predicates in ps */
624 Bool aNumClass = FALSE;
626 if (tyvar(vn)->bound == SKOLEM)
629 /* According to the Haskell definition, we can only default an ambiguous
630 * variable if the set of classes that constrain it:
631 * (a) includes at least one numeric class.
632 * (b) includes only numeric or standard classes.
633 * In addition, we will not allow a variable to be defaulted unless it
634 * appears only in predicates of the form (Class var).
637 #ifdef DEBUG_DEFAULTS
638 printf("Trying to default variable %d\n",vn);
641 for (; nonNull(ps); ps=tl(ps)) {
643 Class c = classConstraining(vn,fst3(pi),intOf(snd3(pi)));
645 if (c==classRealFrac || c==classRealFloat ||
646 c==classFractional || c==classFloating ||
647 c==classReal || c==classIntegral || c==classNum)
649 else if (c!=classEq && c!=classOrd && c!=classShow &&
650 c!=classRead && c!=classIx && c!=classEnum &&
657 { Type t = arg(fst3(pi));/* Check for single var as arg */
658 Int o = intOf(snd3(pi));
661 if (!tyv || tyvNum(tyv)!=vn)
664 if (!cellIsMember(c,cs))
669 /* Now find the first class (if any) in the list of defaults that
670 * is an instance of all of the required classes.
672 * If we get this far, then cs only mentions classes from the list
673 * above, all of which have only a single parameter of kind *.
677 List ds = defaultDefns; /* N.B. guaranteed to be monotypes */
678 #ifdef DEBUG_DEFAULTS
679 printf("Default conditions met, looking for type\n");
681 for (; nonNull(ds); ds=tl(ds)) {
683 while (nonNull(cs1) && nonNull(entail(NIL,ap(hd(cs1),hd(ds)),0)))
687 #ifdef DEBUG_DEFAULTS
688 printf("Default type for variable %d is ",vn);
689 printType(stdout,hd(ds));
697 #ifdef DEBUG_DEFAULTS
698 printf("No default permitted/found\n");
703 static Class local classConstraining(vn,pi,o)
704 Int vn; /* Return class constraining var*/
705 Cell pi; /* vn in predicate pi, or NIL if*/
706 Int o; { /* vn is not involved */
707 for (; isAp(pi); pi=fun(pi))
708 if (!doesntOccurIn(tyvar(vn),arg(pi),o))
713 /*-------------------------------------------------------------------------*/