/
FitsIn.chs
1836 lines (1693 loc) · 83.5 KB
/
FitsIn.chs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
%%[0 lhs2tex
%include lhs2TeX.fmt
%include afp.fmt
%if style == poly
%format t1
%format t2
%format tf1
%format tf2
%format tr1
%format tr2
%format ta1
%format ta2
%format ty1
%format ty2
%format fi1
%format fi2
%format fo1
%format fo2
%format uqt1
%format uqt2
%endif
%%]
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%% Subsumption (fitting in) for types
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%[(1 hmtyinfer) module {%{EH}Ty.FitsIn} import({%{EH}Base.HsName.Builtin},{%{EH}Base.Common}, {%{EH}Base.TermLike}, {%{EH}Ty.FitsInCommon}, {%{EH}Ty}, {%{EH}Error}) export (fitsIn)
%%]
%%[(2 hmtyinfer) import({%{EH}VarMp},{%{EH}Substitutable})
%%]
%%[(4 hmtyinfer) import({%{EH}Ty.Trf.Instantiate}, {%{EH}Ty.FitsInCommon2}, {%{EH}Opts}, {%{EH}Gam.Full}, Data.Maybe,Data.List as List)
%%]
%%[(4 hmtyinfer) import({%{EH}Ty.AppSpineGam})
%%]
%%[(4 hmtyinfer) import(qualified Data.Set as Set)
%%]
%%[(4 hmtyinfer) import(UHC.Util.Utils)
%%]
%%[(8 hmtyinfer) hs import({%{EH}AbstractCore})
%%]
%%[(9 hmtyinfer) import({%{EH}Ty.Trf.Canonic})
%%]
%%[(9 hmtyinfer) import(qualified Data.Map as Map,UHC.Util.Pretty)
%%]
%%[(9 hmtyinfer) import({%{EH}Gam.ClGam},{%{EH}Pred})
%%]
%%[(9 codegen hmtyinfer) import({%{EH}Core},{%{EH}Core.Subst},{%{EH}Core.Coercion})
%%]
%%[(9 codegen coreout hmtyinfer) import({%{EH}Core.Pretty})
%%]
%%[(9 hmtyinfer) import({%{EH}CHR.CtxtRedOnly.Constraint})
%%]
%%[(9 hmtyinfer) export(fitsIn')
%%]
%%[(10 codegen hmtyinfer) import({%{EH}Core.Utils})
%%]
%%[(11 hmtyinfer) import({%{EH}Ty.Trf.BetaReduce})
%%]
%%[(99 hmtyinfer tyderivtree).DerivationTree import({%{EH}DerivationTree})
%%]
%%[(100 hmtyinfer tyderivtree) -99.DerivationTree
%%]
For debug/trace:
%%[(4 hmtyinfer) import(UHC.Util.Pretty,{%{EH}Ty.Pretty},{%{EH}Error.Pretty},{%{EH}Ty.Utils1})
%%]
%%[(4 hmtyinfer) import({%{EH}Base.Debug} as Debug)
%%]
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%% FitsIn Input
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%[(4 hmtyinfer)
%%[[4
fiAppVarMp :: FIIn -> Ty -> Ty
%%][8
fiAppVarMp :: VarUpdatable Ty gm => FIIn' gm -> Ty -> Ty
%%]]
fiAppVarMp fi x = fiVarMpLoc fi `varUpd` (fiVarMp fi `varUpd` x)
%%]
%%[(9 hmtyinfer)
instance Show (FIIn' gm) where
show _ = "FIIn"
instance PP (FIIn' gm) where
pp fi = "FIIn:" >#< pp (fiEnv fi)
%%]
%%[(4 hmtyinfer).fiUpdOpts
fiUpdOpts :: (FIOpts -> FIOpts) -> FIIn' gm -> FIIn' gm
fiUpdOpts upd fi = fi {fiFIOpts = upd (fiFIOpts fi)}
%%]
%%[(4 hmtyinfer)
fiInhibitVarExpandL :: TyVarId -> FIIn' gm -> FIIn' gm
fiInhibitVarExpandL v fi = fi {fiExpLTvS = v `Set.insert` fiExpLTvS fi}
fiVarIsExpandedL :: TyVarId -> FIIn' gm -> Bool
fiVarIsExpandedL v fi = v `Set.member` fiExpLTvS fi
fiInhibitVarExpandR :: TyVarId -> FIIn' gm -> FIIn' gm
fiInhibitVarExpandR v fi = fi {fiExpRTvS = v `Set.insert` fiExpRTvS fi}
fiVarIsExpandedR :: TyVarId -> FIIn' gm -> Bool
fiVarIsExpandedR v fi = v `Set.member` fiExpRTvS fi
%%]
%%[(4 hmtyinfer)
fiSwapCoCo :: FIIn' gm -> FIIn' gm
fiSwapCoCo fi = fi {fiExpLTvS = fiExpRTvS fi, fiExpRTvS = fiExpLTvS fi}
%%]
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%% Lookup of AppSpine + Polarity
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
Get the type level spine info, in particular how co/contra variance should propagate from type application to its arguments.
The polarity for a type constructor is used for that purpose.
The implementation matches the polarity against a -> b -> Covariant, and observes values for a and b.
In case of failure, the worst is assumed and all is invariant.
TBD: failure should not happen, the encoding of polarity is too strict by not matching Invariant <= Covariant, thus failing.
%%[(4 hmtyinfer)
%%[[4
fiAppSpineLookup :: FIIn' gm -> HsName -> AppSpineGam -> Maybe AppSpineInfo
fiAppSpineLookup fi n gappSpineGam = asGamLookup n $ feAppSpineGam $ fiEnv fi
%%][17
fiAppSpineLookup
:: forall gm .
( VarLookupCmb VarMp gm
, VarLookup gm
, VarLookupKey gm ~ TyVarId, VarLookupVal gm ~ VarMpInfo
)
=> FIIn' gm -> HsName -> AppSpineGam -> Maybe AppSpineInfo
fiAppSpineLookup fi n gappSpineGam
= case (asGamLookup n $ feAppSpineGam $ fiEnv fi,polGamLookup n (fePolGam $ fiEnv fi)) of
(Just asi, Just pgi)
-> Just $ upd pgi asi
(_,Just pgi)
-> Just $ upd pgi emptyAppSpineInfo
(mbasi,_)
-> mbasi
where upd pgi asi
| foHasErrs fo = asi
| otherwise = asi {asgiVertebraeL = zipWith asUpdateByPolarity (appUnArrArgs $ tyCanonic (emptyTyBetaRedEnv' emptyFE) $ foVarMp fo `varUpd` foTy fo) (asgiVertebraeL asi)}
where pol = pgiPol pgi
(polargs,polres) = appUnArr pol
(_,u1,u2) = mkNewLevUID2 uidStart
fo = fitsIn weakFIOpts emptyFE u1 (emptyVarMp :: VarMp) pol (map mkPolVar (mkNewUIDL (length polargs) u2) `appArr` polCovariant)
%%]]
%%]
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%% Subsumption
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%[fitsInHead.1
fitsIn :: Ty -> Ty -> FIOut
fitsIn ty1 ty2
= f ty1 ty2
where
res t = emptyFO {foTy = t}
%%]
%%[fitsInBotCon.1
f Ty_Any t2 = res t2 -- m.any.l
f t1 Ty_Any = res t1 -- m.any.r
f t1@(Ty_Con s1) -- m.con
t2@(Ty_Con s2)
| s1 == s2 = res t2
%%]
%%[fitsInBind.2
bind tv t = (res t) {foVarMp = tv `varmpTyUnit` t}
occurBind v t | v `elem` varFree t
= err [Err_UnifyOccurs ty1 ty2 v t]
| otherwise = bind v t
%%]
%%[fitsInapp.1
comp tf1 ta1 tf2 ta2 mkComp
= foldr1 (\fo1 fo2 -> if foHasErrs fo1 then fo1 else fo2)
[ffo,afo,res rt]
where ffo = f tf1 tf2
afo = f ta1 ta2
rt = mkComp (foTy ffo) (foTy afo)
%%]
%%[fitsInapp.2
comp tf1 ta1 tf2 ta2 mkComp
= foldr1 (\fo1 fo2 -> if foHasErrs fo1 then fo1 else fo2)
[ffo,afo,rfo]
where ffo = f tf1 tf2
fs = foVarMp ffo
afo = f (fs `varUpd` ta1) (fs `varUpd` ta2)
as = foVarMp afo
rt = mkComp (as `varUpd` foTy ffo) (foTy afo)
rfo = emptyFO {foTy = rt, foVarMp = as `varUpd` fs}
%%]
%%[fitsInApp.1
f t1@(Ty_App (Ty_App (Ty_Con c1) ta1) tr1) -- m.arrow
t2@(Ty_App (Ty_App (Ty_Con c2) ta2) tr2)
| hsnIsArrow c1 && c1 == c2
= comp ta2 tr1 ta1 tr2 (\a r -> [a] `appArr` r)
f t1@(Ty_App tf1 ta1) -- m.prod
t2@(Ty_App tf2 ta2)
= comp tf1 ta1 tf2 ta2 Ty_App
%%]
%%[fitsInRest.1
f t1 t2 = err [Err_UnifyClash ty1 ty2 t1 t2]
err e = emptyFO {foErrL = e}
%%]
%%[(1 hmtyinfer).fitsIn.Base
%%@fitsInHead.1
%%@fitsInBotCon.1
%%]
%%[(1 hmtyinfer).fitsIn.AppRest
%%@fitsInApp.1
%%@fitsInRest.1
%%@fitsInapp.1
%%]
%%[(2 hmtyinfer).fitsIn.Base -(1.fitsIn.Base 1.fitsIn.AppRest)
%%@fitsInHead.1
%%]
%%[(2 hmtyinfer).fitsIn.Bind
%%@fitsInBind.2
%%]
%%[(2 hmtyinfer).fitsIn.app
%%@fitsInapp.2
%%]
%%[(2 hmtyinfer).fitsIn.BotCon
%%@fitsInBotCon.1
%%]
%%[(2 hmtyinfer).fitsIn.Var
f t1@(Ty_Var v1) (Ty_Var v2)
| v1 == v2 = res t1
f t1@(Ty_Var v1) t2 = occurBind v1 t2
f t1 t2@(Ty_Var v2) = occurBind v2 t1
%%]
%%[(2 hmtyinfer).fitsIn.AppRest
%%@fitsInApp.1
%%@fitsInRest.1
%%]
%%[fitsInVar.3
f t1@(Ty_Var v1 f1) (Ty_Var v2 f2)
| v1 == v2 && f1 == f2 = res t1
f t1@(Ty_Var v1 f) t2
| f == TyVarCateg_Plain = occurBind v1 t2
f t1 t2@(Ty_Var v2 f)
| f == TyVarCateg_Plain = occurBind v2 t1
%%]
%%[(3 hmtyinfer).fitsIn -(2.fitsIn.Base 2.fitsIn.Bind 2.fitsIn.app 2.fitsIn.BotCon 2.fitsIn.Var 2.fitsIn.AppRest)
%%@fitsInHead.1
%%@fitsInBind.2
%%@fitsInapp.2
%%@fitsInBotCon.1
%%@fitsInVar.3
%%@fitsInApp.1
%%@fitsInRest.1
%%]
%%[(4 hmtyinfer).fitsIn.Prelim -3.fitsIn
manyFO :: [FIOut] -> FIOut
manyFO = foldr1 (\fo1 fo2 -> if foHasErrs fo1 then fo1 else fo2)
fitsIn
:: forall gm .
{- ( VarUpdatable Ty gm
, VarLookupCmb VarMp gm
, VarLookupCmb gm gm
)
=> -}
( VarLookup gm
, VarLookupCmb VarMp gm
, VarLookupKey gm ~ VarId, VarLookupVal gm ~ VarMpInfo
)
=> FIOpts -> FIEnv -> UID -> gm -> Ty -> Ty
-> FIOut
fitsIn opts env uniq varmp
= fitsInFI
((emptyFI
{ fiUniq = uniq
, fiFIOpts = opts
, fiVarMp = varmp
%%[[8
, fiEnv = env
%%]]
}
) :: FIIn' gm
)
%%]
%%[(4 hmtyinfer).fitsInFI
%%[[4
fitsInFI :: FIIn -> Ty -> Ty -> FIOut
%%][8
fitsInFI
:: forall gm .
{- ( VarUpdatable Ty gm
, VarLookupCmb VarMp gm
, VarLookupCmb gm gm
)
=> -}
( VarLookup gm
, VarLookupCmb VarMp gm
, VarLookupKey gm ~ VarId, VarLookupVal gm ~ VarMpInfo
)
=> FIIn' gm -> Ty -> Ty
-> FIOut
%%]]
fitsInFI fi ty1 ty2
= foRes {foTrace = reverse $ foTrace foRes}
where
%%[[4
appSpineGam = feAppSpineGam $ fiEnv fi
%%]]
%%[[8
-- options
globOpts = feEHCOpts $ fiEnv fi
%%]]
-- range where fitsIn takes place
%%[[1
range = emptyRange
%%][99
range = feRange $ fiEnv fi
%%]]
-- tracing
%%[[4
trfiAdd tr fi = fi {fiTrace = tr ++ fiTrace fi}
trfi msg rest fi = trfiAdd [trfitIn msg rest] fi
trfoAdd tr fo = fo {foTrace = tr ++ foTrace fo}
trfo msg rest fo = trfoAdd [trfitOu msg rest] fo
%%][100
trfiAdd tr fi = fi
trfi msg rest fi = fi
trfoAdd tr fo = fo
trfo msg rest fo = fo
%%]]
-- derivation tree
%%[[4
dtfo _ _ _ _ _ _ fo = fo
%%][9999
-- following goes wrong because foMkDT must refer to same gm as FIIn' gm, which means FIOut must be parameterized as well
dtfo rlNm fi t1 t2 subfos mbind fo
= fo {foMkDT = mk}
where mk mbTop fmt m dm1 = ( dtRule False fmt ("m." ++ rlNm) (reverse subs) (dtJdgMatch opts fiopts t1' t2' t3 mbnd), dm5 )
where (t1' ,dm2) = dtEltTy (dtChooseDT opts m mfi) dm1 t1
(t2' ,dm3) = dtEltTy (dtChooseDT opts m mfi) dm2 t2
(subs,dm4) = foldl (\(subs,dm) (fo,fmt) -> let (sub,dm') = foMkDT fo Nothing fmt m dm in (sub:subs,dm')) ([],dm3) subfos
(t3 ,dm5) = dtEltTy (dtChooseDT opts m mfo) dm4 (foTy fo)
(mbnd,dm6) = maybe (dtEltVarMp (dtChooseDT opts m mfo) dm5 mbind) (\x -> (x,emptyVarMp)) mbTop
mfi = fiVarMpLoc fi |+> fiVarMp fi
mfo = foVarMp fo |+> fiVarMp fi
opts = feEHCOpts $ fiEnv fi
fiopts = fiFIOpts fi
%%][100
dtfo _ _ _ _ _ _ fo = fo
%%]]
-- results
res' fi tv t = updtr $ (fifo fi emptyFO) {foTy = tv, foMbAppSpineInfo = fiAppSpineLookup fi (tyConNm t) appSpineGam}
%%[[4
where updtr fo = trfo "res" (ppTyWithFI fi tv >|< ", spine" >#< (tyConNm t) >|< ":" >#< pp (foAppSpineInfo fo) {- >-< "polgam:" >#< ppGam (fePolGam $ fiEnv fi) -}) fo
%%][100
where updtr = id
%%]]
res fi t = res' fi t t
-- errors
err fi e = trfo "err" (ppErrL e)
$ emptyFO {foUniq = fioUniq (fiFIOpts fi), foErrL = e, foTrace = fiTrace fi}
%%[[4
errClash fiErr t1 t2 = dflt
%%][93
errClash fiErr t1 t2 = maybe dflt (\mk -> err fiErr [mk ty1 ty2]) $ fiMbMkErrClash $ fiFIOpts fiErr
%%]]
where dflt = err fiErr [rngLift range Err_UnifyClash (fiAppVarMp fiErr ty1) (fiAppVarMp fiErr ty2) (fioMode (fiFIOpts fi)) (fiAppVarMp fiErr t1) (fiAppVarMp fiErr t2) (fioMode (fiFIOpts fiErr))]
-- binding
occurBind fi isLBind v t= bind fi isLBind v t
%%]
%%[(4 hmtyinfer)
-- 20080309, AD: naming of function is not right, type info neither, error yes. Should indicate a double expansion of tyvar, indicating infinite type.
errInfinite fi v t = err fi [rngLift range Err_UnifyOccurs (fiAppVarMp fi ty1) (fiAppVarMp fi ty2) (fioMode (fiFIOpts fi)) v t (fioMode (fiFIOpts fi))]
%%]
%%[(9 hmtyinfer).fitsIn.lookupImplsVar
lookupImplsVarCyc fi v = fiLookupVar' varmpImplsLookupCyc varmpImplsLookupCyc v (fiVarMpLoc fi) (fiVarMp fi)
%%]
%%[(10 hmtyinfer).fitsIn.lookupLabelVarCyc
lookupLabelCyc fi v = fiLookupVar' varmpLabelLookupLabelCyc varmpLabelLookupLabelCyc v (fiVarMpLoc fi) (fiVarMp fi)
%%]
%%[(4 hmtyinfer).fitsIn.bind
bind fi isLBind tv t = dtfo "bind" fi tv' t [] (tv `varmpTyUnit` t)
%%[[4
$ trfo "bind" ("tv:" >#< tv >-< "ty:" >#< ppTyWithFI fi t)
%%][100
%%]]
$ res' (fiBindTyVar tv t fi2) tv' t
where tv' = mkTyVar tv
%%[[4
fi2 = fi
%%][9
fi2 = case (tyMbVar t, (if isLBind then fioBindRVars else fioBindLVars) (fiFIOpts fi)) of
(Just v, FIOBindNoBut but) | not (v `Set.member` but)
-> -- (\x -> let o = fiFIOpts x in Debug.tr "fitsIn.bind.fi2" (isLBind >#< tv >#< t >-< show (fioBindRVars o) >#< show (fioBindLVars o) >-< show (fioDontBind $ fiFIOpts fi) >#< show (fioDontBind o)) x) $
fiInhibitBind v fi
_ -> fi
%%]]
%%]
%%[(4 hmtyinfer).fitsIn.allowImpredTVBind
allowImpredTVBindL fi t _
= fioBindLFirst (fiFIOpts fi) && fiAllowTyVarBind fi t
allowImpredTVBindR fi t _
= fioBindRFirst (fiFIOpts fi) && fiAllowTyVarBind fi t
%%]
%%[(4 hmtyinfer).fitsIn.unquant
-- removal of quantifier
unquant fi t hide howToInst
= ( fi { fiUniq = u
%%[[6
, fiVarMpLoc = instToL1VarMp instto |+> fiVarMpLoc fi
%%]]
}
, uqt,back,instto
)
where (u,uq) = mkNewLevUID (fiUniq fi)
(uqt,rtvs,instto) = tyInst1Quants uq howToInst t
back = if hide then \fo -> foSetVarMp (varmpDel rtvs (foVarMp fo)) $ foUpdTy t fo
else id
-- removal of multiple quantifiers
unquants fi t@(Ty_TBind {qu_Ty_TBind=q}) qu howToInst | qu `tyquEqModuloLev` q
= unquants fi' t' qu howToInst
where (fi', t', _, _) = unquant fi t False howToInst
unquants fi t _ _
= (fi, t)
%%]
%%[(41 hmtyinfer).fitsIn.eqProofAssume
eqAssume p fi t1 t2 isRec isSum
= out { foGathCnstrMp = foGathCnstrMp out `Map.union` mp }
where
mp = cnstrMpFromList [cnstr]
cnstr = rngLift range mkAssumeConstraint p lUniq scope
scope = fePredScope $ fiEnv fi
(gUniq,lUniq) = mkNewLevUID (fiUniq fi)
fi' = fi { fiUniq = gUniq }
out = fRow fi' t1 t2 isRec isSum
%%]
%%[(41 hmtyinfer).fitsIn.eqProofObligation
eqProofObligation tRes fi tL tR
= (res fi tRes) { foGathCnstrMp = mp }
where
mp = cnstrMpFromList [cnstr]
cnstr = rngLift range mkProveConstraint (Pred_Eq tL tR) uid scope
scope = fePredScope $ fiEnv fi
uid = fiUniq fi
%%]
%%[(41 hmtyinfer).fitsIn.isSkVar
-- is skolemnized tyvar?
isSkVar = isSkVar' . show
isSkVar' ('C':'_':_) = True
isSkVar' _ = False
%%]
%%[(4 hmtyinfer).fitsIn.FOUtils
foUpdVarMp c fo = fo {foVarMp = c |+> foVarMp fo}
fifo fi fo = fo { foVarMp = fiVarMpLoc fi, foUniq = fiUniq fi, foTrace = fiTrace fi
%%[[7
, foDontBind = fioDontBind (fiFIOpts fi)
%%]]
}
fofi fo fi = -- (\x -> Debug.tr "fofi" ((pp $ show $ fioDontBind o) >-< (pp $ show $ foDontBind fo) >-< (pp $ show $ fioDontBind $ fiFIOpts x)) x)
fi { fiVarMpLoc = foVarMp fo, fiUniq = foUniq fo, fiTrace = foTrace fo
%%[[7
, fiFIOpts = o {fioDontBind = foDontBind fo}
%%]]
}
where o = fiFIOpts fi
%%]
%%[(7 hmtyinfer)
fiInhibitBind v fi = fi {fiFIOpts = o {fioDontBind = v `Set.insert` fioDontBind o}}
where o = fiFIOpts fi
%%]
%%[(4 hmtyinfer).fitsIn.FOUtils
foUpdTy t fo = fo {foTy = t}
%%]
%%[(4 hmtyinfer).fitsIn.foCmb
foCmbAppTy ffo afo = afo {foTy = Ty_App (foTy ffo) (foTy afo)}
foCmbVarMp ffo afo = afo -- {foVarMp = foVarMp afo `varUpd` foVarMp ffo}
foCmbCoCon ffo afo = afo {foMbAppSpineInfo = fmap asgiShift1SpinePos $ foMbAppSpineInfo ffo}
%%]
%%[(9 hmtyinfer)
foCmbPrL ffo afo = afo {foPredOccL = foPredOccL afo ++ foPredOccL ffo, foGathCnstrMp = foGathCnstrMp afo `cnstrMpUnion` foGathCnstrMp ffo}
%%]
%%[(9 codegen hmtyinfer)
foCmbCSubst ffo afo = afo {foCSubst = cSubstApp (foCSubst afo) (foCSubst ffo)}
%%]
%%[(4 hmtyinfer).fitsIn.foCmbApp
foCmbApp ffo =
%%[[6
-- foCmbTvKiVarMp ffo .
%%]]
%%[[7
-- (\afo -> afo {foDontBind = ((\x -> Debug.tr "foCmbApp.ffo" (pp $ show x) x) $ foDontBind ffo) `Set.union` ((\x -> Debug.tr "foCmbApp.afo" (pp $ show x) x) $ foDontBind afo)}) .
%%]]
%%[[9
foCmbPrfRes ffo .
%%]]
foCmbCoCon ffo . foCmbVarMp ffo . foCmbAppTy ffo
%%]
%%[(7 hmtyinfer).fitsIn.foCmbPrfRes
foCmbPrfRes ffo afo = afo
%%]
%%[(9 hmtyinfer).fitsIn.foCmbPrfRes -7.fitsIn.foCmbPrfRes
foCmbPrfRes ffo = foCmbPrL ffo
%%[[(9 codegen)
. foCmbCSubst ffo
%%]]
%%]
%%[(9 hmtyinfer)
fiAddPr n i prTy fi
= let e = fiEnv fi
(_,assumePredScope) = pscpEnter 0 $ fePredScope (fiEnv fi)
pr = tyPred prTy
in (fi { fiEnv = e {fePredScope = assumePredScope} },gathPredLToAssumeCnstrMp [rngLift range mkPredOccRng pr i assumePredScope])
foUpdErrs e fo = fo {foErrL = e ++ foErrL fo}
foUpdCnstrMp m fo = fo {foGathCnstrMp = m `cnstrMpUnion` foGathCnstrMp fo}
foUpdPrL prL prMp fo = foUpdCnstrMp prMp $ fo {foPredOccL = prL ++ foPredOccL fo}
foUpdImplExpl iv im tpr fo
= foUpdVarMp (iv `varmpImplsUnit` im)
$ foUpdTy ([tpr] `appArr` foTy fo)
$ fo
%%[[(9 codegen)
foUpdLRCoe lrcoe fo = fo {foLRCoe = lrcoe `lrcoeUnion` foLRCoe fo}
%%]]
%%[[8
foUpdImplExplCoe iv im tpr
%%[[(9 codegen)
lrcoe
%%]]
fo
= foUpdImplExpl iv im tpr
%%[[(9 codegen)
$ foUpdLRCoe lrcoe
%%]]
fo
%%]]
%%]
A counterpart type to enforce deep quantifier instantiation.
20080606, AD: Omitting the check on hsnPolNegation breaks polarity matching; this has to be sorted out.
%%[(4 hmtyinfer)
deepInstMatchTy fi t
= case t of
_ | not (null as
%%[[17
|| tyConNm f == hsnPolNegation
%%]]
)
-> Just (appTopApp $ mkNewTyVarL (length as + 1) u1, fi')
| otherwise -> Nothing
where (f,as) = appUnApp t
where (u,u1) = mkNewLevUID (fiUniq fi)
fi' = fi {fiUniq = u}
%%]
%%[(7 hmtyinfer)
fPairWise fi tL1 tL2
= foldr (\(t1,t2) (foL,fii)
-> let fo = fVar' fTySyn fii id t1 t2
in (fo:foL,fofi fo fii))
([],fi)
(zip tL1 tL2)
%%]
GADT: when encountering a product with eq-constraints on the outset, remove them and bring them in scope as assume constraints
%%[(41 hmtyinfer).fitsIn.fRow.StripPreds
fRow fi (Ty_Ext t1 _ (Ty_Pred p)) t2 isRec isSum = eqAssume p fi t1 t2 isRec isSum
fRow fi t1 (Ty_Ext t2 _ (Ty_Pred p)) isRec isSum = eqAssume p fi t1 t2 isRec isSum
%%]
%%[(7 hmtyinfer).fitsIn.fRow.Base
fRow fi tr1 tr2 isRec isSum
= foR
where (r1,exts1) = tyRowExtsUnAnn $ tyRowExtsWithLkup (fiLookupTyVarCyc fi) tr1
(r2,exts2) = tyRowExtsUnAnn $ tyRowExtsWithLkup (fiLookupTyVarCyc fi) tr2
(extsIn1,extsIn12,extsIn2) = split (rowCanonOrder exts1) (rowCanonOrder exts2)
split ees1@(e1:es1) ees2@(e2:es2)
= case e1 `rowExtCmp` e2 of
EQ -> let (es1',es12,es2') = split es1 es2 in (es1',(e1,e2):es12,es2')
LT -> let (es1',es12,es2') = split es1 ees2 in (e1:es1',es12,es2')
GT -> let (es1',es12,es2') = split ees1 es2 in (es1',es12,e2:es2')
split ees1 ees2
= (ees1,[],ees2)
mkTv fi = (fi',mkTyVar u)
where (u',u) = mkNewUID (fiUniq fi)
fi' = fi {fiUniq = u'}
bind fo v r e = manyFO [fo,foUpdTy (foTy fo `recRow` e) $ foUpdVarMp (v `varmpTyUnit` recRow r e) $ fo]
(u',u1) = mkNewLevUID (fiUniq fi)
fi2 = fi {fiUniq = u'}
fR fi r1 r2@(Ty_Var v2 f2) e1@(_:_) e12 e2
| fiAllowTyVarBind fi r2
= bind (fR fi2 r1 rv [] e12 e2) v2 rv e1
where (fi2,rv) = mkTv fi
fR fi r1@(Ty_Var v1 f1) r2 e1 e12 e2@(_:_)
| fiAllowTyVarBind fi r1
= bind (fR fi2 rv r2 e1 e12 []) v1 rv e2
where (fi2,rv) = mkTv fi
fR fi r1@(Ty_Con n1) _ _ _ e2@(_:_)
| n1 == hsnRowEmpty && isRec
= err fi [rngLift range Err_MissingRowLabels (assocLKeys e2) (fiAppVarMp fi tr1)]
{-
fR fi r1 r2@(Ty_Con n2) e1@(_:_) e12 e2
| n2 == hsnRowEmpty && isRec && not (null labs)
= err fi [rngLift range Err_MissingRowLabels labs (fiAppVarMp fi tr2)]
where labs = fioNoLLabElimFor (fiFIOpts fi) `List.intersect` assocLKeys e1
-}
fR fi r1 r2@(Ty_Con n2) e1@(_:_) e12 e2
| n2 == hsnRowEmpty && isRec
= if null labs
then fR fi r1 r2 [] e12 e2
else err fi [rngLift range Err_TooManyRowLabels (assocLKeys e1) (fiAppVarMp fi tr2)]
where labs = fioNoRLabElimFor (fiFIOpts fi) `List.intersect` assocLKeys e1
fR fi r1@(Ty_Con n1) r2 e1 e12 e2@(_:_)
| n1 == hsnRowEmpty && isSum
= fR fi r1 r2 e1 e12 []
fR fi r1 r2@(Ty_Con n2) e1@(_:_) e12 e2
| n2 == hsnRowEmpty && isSum
= err fi [rngLift range Err_MissingRowLabels (assocLKeys e1) (fiAppVarMp fi tr2)]
fR fi r1 r2 e1 e12@(_:_) e2
= foR
where (e1L,e2L) = unzip e12
(foL,fi2) = fPairWise ({- fiUpdOpts fioMkStrong -} fi) (assocLElts e1L) (assocLElts e2L)
eKeys = assocLKeys e1L
eL = zip eKeys (map foTy foL)
fo = fR fi2 r1 r2 e1 [] e2
foR = manyFO ([fo] ++ foL ++ [foRes])
foRes = (\fo -> foldr foCmbPrfRes fo foL)
%%[[10
$ foUpdRecFldsCoe eKeys foL tr1
%%]]
$ foUpdTy (foTy fo `recRow` eL) fo
%%]
%%[(7 hmtyinfer).fitsIn.fRow.fRFinal
fR fi r1 r2 [] [] []
= f fi r1 r2
%%]
%%[(10 hmtyinfer).fitsIn.fRow.fRFinal -7.fitsIn.fRow.fRFinal
fR fi r1@(Ty_Var _ f1) r2@(Ty_Con n2) [] [] []
| tvCatIsFixed f1 && n2 == hsnRowEmpty && isRec
= res fi r2
fR fi r1@(Ty_Var v1 f1) r2@(Ty_Con n2) [] [] []
| f1 `elem` fioBindCategs (fiFIOpts fi) {- tvCatIsPlain f1 -} && n2 == hsnRowEmpty && isRec
= occurBind fi True v1 r2
fR fi r1 r2 [] [] []
= (fBase fi id r1 r2)
%%[[(10 codegen)
{ foLRCoe = emptyLRCoe
}
%%]]
%%]
fR fi r1@(Ty_Var _ cat) r2@(Ty_Con n2) [] [] []
| tvCatIsFixed cat && n2 == hsnRowEmpty && isRec
= res fi r2
fR fi r1 r2 [] [] []
= (f fi r1 r2)
{ foLRCoe = emptyLRCoe
, foLRTCoe = C.emptyLRCoe
}
%%[(7 hmtyinfer).fitsIn.fRow.Final1
fR fi _ _ _ _ _
= errClash fi tr1 tr2
%%]
%%[(7 hmtyinfer).fitsIn.fRow.foR
foR = fR fi2 r1 r2 extsIn1 extsIn12 extsIn2
%%]
%%[(10 hmtyinfer).fitsIn.fRow.foR -7.fitsIn.fRow.foR
fo = fR fi2 r1 r2 extsIn1 extsIn12 extsIn2
foR = (if isRec then foUpdRecCoe tr1 r1 r2 extsIn1 extsIn12 extsIn2 else id) fo
foUpdRecCoe tr1 r1 r2 e1 e12 e2 fo
= let rn = uidHNm u1
predScope = fePredScope (fiEnv fi)
-- tr1s = foVarMp fo `varUpd` tr1
fi3 = fofi fo fi2
tr1s = uncurry recRow $ tyRowExtsUnAnn $ tyRowExtsWithLkup (fiLookupTyVarCyc fi3) tr1
(u',u2,u3,u4) = mkNewLevUID3 (foUniq fo)
%%[[(10 codegen)
r = acoreVar rn
mkLSel n u = acoreSelCaseTy (emptyRCEEnv globOpts) (Just (hsnUniqifyEval rn,acoreTyErr "fitsIn.mkLSel")) r CTagRec n {-n-} (acoreNmHole u) Nothing
%%]]
mkLPred' r l u
= let r' = maybe Ty_Any fst $ tyRowExtr l r
in (rngLift range mkPredOccRng (Pred_Lacks r' (Label_Lab l)) (mkPrIdCHR u) predScope,r')
mkLPred r l u = fst (mkLPred' r l u)
%%[[10
rowCoeL = sortByOn rowLabCmp fst (foRowCoeL fo)
-- rowCoeL = sortByOn rowLabCmp fst $ map fst extsIn12
%%]]
%%[[(10 codegen)
(fuUpdL,prUpdL,tr1s',csubstUpd,_)
= foldr (\(l,c) (fuL,prL,r,csubst,u)
%%][10
(fuUpdL,prUpdL,tr1s',_)
= foldr (\(l,c) (fuL,prL,r,u)
%%]]
-> let (u',u1,u2) = mkNewLevUID2 u
%%[[(10 codegen)
(sel,csubstSel) = coeEvalOnAsSubst u2 c (mkLSel l u1)
%%]]
in ( ( l
%%[[(10 codegen)
, (CExpr_TupUpd (acoreBuiltinUndefined globOpts) CTagRec l (acoreNmHole u) sel,Nothing)
%%]]
) : fuL
, mkLPred r l u1 : prL
, r
%%[[(10 codegen)
, csubst `cSubstApp` csubstSel
%%]]
, u'
)
)
%%[[(10 codegen)
([],[],tr1s,emptyCSubst,u2)
%%][10
([],[],tr1s,u2)
%%]]
rowCoeL
(fuDelL,prDelL,_,_)
= foldl (\(fuL,prL,r,u) l
-> let (pr,r') = mkLPred' r l u
in ( ( l
%%[[(10 codegen)
, (CExpr_TupDel (acoreVar hsnWild) CTagRec l (acoreNmHole u),Nothing)
%%]]
) : fuL
, pr:prL,r',uidNext u
)
)
([],[],tr1s',u3) (sortBy rowLabCmp (assocLKeys e1))
fuL = fuUpdL ++ reverse fuDelL
%%[[(10 codegen)
(prBldL, fBldL, _, csubstBld, _)
= foldr (\l (prL,fL,r,csubst,u)
%%][10
(prBldL, fBldL, _, _)
= foldr (\l (prL,fL,r,u)
%%]]
-> let (u',u1,u2) = mkNewLevUID2 u
%%[[(10 codegen)
(sel,csubstSel)
= maybe (s,emptyCSubst) (\c -> coeEvalOnAsSubst u2 c s) (lookup l rowCoeL)
where s = mkLSel l u1
%%]]
in ( mkLPred r l u1 : prL,
%%[[(10 codegen)
sel :
%%]]
fL
, r
%%[[(10 codegen)
, csubst `cSubstApp` csubstSel
%%]]
, u'
)
)
%%[[(10 codegen)
([], [], tr1s, emptyCSubst, u3)
%%][10
([], [], tr1s, u3)
%%]]
(sortBy rowLabCmp ((assocLKeys . map fst $ e12) ++ assocLKeys e2))
in case r2 of
Ty_Con n2
| n2 == hsnRowEmpty && null fuL && null e2
-> fo
%%[[(10 codegen)
{ foLRCoe = emptyLRCoe
, foCSubst = foCSubst fo `cSubstApp` csubstUpd `cSubstApp` csubstBld
}
%%]]
{- -- when ext rec deletes are implemented
| n2 == hsnRowEmpty && null fuUpdL && not (null fuDelL) && null e2
-> let coe = Coe_Map (\e -> acoreLet CBindCateg_Plain [CBind_Bind rn e] (fuMkCExpr globOpts u4 fuDelL r))
in fo { foLRCoe = lrcoeLSingleton coe
, foPredOccL = prDelL ++ foPredOccL fo
, foGathCnstrMp = gathPredLToProveCnstrMp prDelL `cnstrMpUnion` foGathCnstrMp fo
, foUniq = u'
}
-}
| n2 == hsnRowEmpty && not (null prBldL)
-> let
%%[[(10 codegen)
coe = Coe_Map (\e -> acoreLet1Plain rn e (acoreTagTupTy CTagRec (acoreTyErr "fitsIn.foUpdRecCoe.coe") fBldL))
%%]]
in fo { foPredOccL = prBldL ++ foPredOccL fo
, foGathCnstrMp = gathPredLToProveCnstrMp prBldL `cnstrMpUnion` foGathCnstrMp fo
, foUniq = u'
%%[[(10 codegen)
, foLRCoe = lrcoeLSingleton coe
%%]]
}
Ty_Var _ cat
| tvCatIsFixed cat && not (null fuL)
-> fo { foPredOccL = prUpdL ++ prDelL ++ foPredOccL fo
, foGathCnstrMp = gathPredLToProveCnstrMp (prUpdL ++ prDelL) `cnstrMpUnion` foGathCnstrMp fo
, foUniq = u'
%%[[(10 codegen)
, foLRCoe = lrcoeLSingleton coe
%%]]
}
%%[[(10 codegen)
where coe = Coe_Map (\e -> acoreLet1Plain rn e (fuMkCExpr globOpts u4 fuL r))
%%]]
_ | not (null fuUpdL)
-> fo { foPredOccL = prUpdL ++ foPredOccL fo
, foGathCnstrMp = gathPredLToProveCnstrMp prUpdL `cnstrMpUnion` foGathCnstrMp fo
, foUniq = u'
%%[[(10 codegen)
, foLRCoe = lrcoeLSingleton coe
%%]]
}
| otherwise
-> fo
%%[[(10 codegen)
{ foLRCoe = emptyLRCoe
}
%%]]
%%[[(10 codegen)
where coe = Coe_Map (\e -> acoreLet1Plain rn e (fuMkCExpr globOpts u4 fuUpdL r))
%%]]
%%]
%%[(10 hmtyinfer).fitsIn.fRow.Coe
foUpdRecFldsCoe eKeys foL tr1 foR
= let (u',u1) = mkNewLevUID (foUniq foR)
%%[[(10 codegen)
us = mkNewLevUIDL (length foL) u1
(cL,sL)
= unzip
[ ((l,c),s)
| (l,fo,u) <- zip3 eKeys foL us
, let (c,s) = lrcoeWipeWeaveAsSubst globOpts u (foVarMp foR) (foLRCoe fo)
, not (acoreCoeIsId c)
]
%%][10
cL = [ (l,Coe_NONE) | l <- eKeys ]
%%]]
in foR { foUniq = u'
%%[[10
, foRowCoeL = cL
%%]]
%%[[(10 codegen)
, foCSubst = foldr cSubstApp (foCSubst foR) sL
%%]]
}
%%]
%%[(4 hmtyinfer)
f fi t1 t2
= fBase fi id t1 t2
%%]
%%[(4 hmtyinfer).fitsIn.fTySyn
fTySyn fi updTy t1 t2
= fBase fi updTy t1 t2
%%]
%%[(11 hmtyinfer) -4.fitsIn.fTySyn
fTySyn fi updTy t1 t2
= case filter (not . foHasErrs) tries of
(fo:_) -> fo
_ -> case (drop limit rt1, drop limit rt2, tries) of
((t:_),_ ,_ ) -> err (trfiAdd (tbroutTracePPL t) fi2) [rngLift range Err_TyBetaRedLimit (fiAppVarMp fi2 t1) (fiAppVarMp fi2 (tbroutRes t)) limit]
(_ ,(t:_),_ ) -> err (trfiAdd (tbroutTracePPL t) fi2) [rngLift range Err_TyBetaRedLimit (fiAppVarMp fi2 t2) (fiAppVarMp fi2 (tbroutRes t)) limit]
(_ ,_ ,ts@(_:_)) -> last ts
(_ ,_ ,_ ) -> errClash fi2 t1 t2
where limit = ehcOptTyBetaRedCutOffAt globOpts
%%[[11
fi2 = trfi "fTySyn" ("t1:" >#< ppTyWithFI fi t1 >-< "t2:" >#< ppTyWithFI fi t2) fi
%%][100
fi2 = fi
%%]]
rt1 = tyBetaRedAndInit (emptyTyBetaRedEnv {tbredFI=fi2}) betaRedTyLookup t1
rt2 = tyBetaRedAndInit (emptyTyBetaRedEnv {tbredFI=fi2}) betaRedTyLookup t2
tries = take (limit+1) $ try fi2 (rt1) (rt2)
where -- get the pairwise fitsIn of further and further expanded synonyms
try fi (t1:ts1@(_:_)) (t2:ts2@(_:_)) = (ok t1 t2 $ fBase fi' updTy (tbroutRes t1) (tbroutRes t2)) ++ try fi' ts1 ts2
where fi' = trfiAdd (tbroutTracePPL t1) $ trfiAdd (tbroutTracePPL t2) fi
try fi ts1@[t1] (t2:ts2@(_:_)) = (ok t1 t2 $ fBase fi' updTy (tbroutRes t1) (tbroutRes t2)) ++ try fi' ts1 ts2
where fi' = trfiAdd (tbroutTracePPL t2) fi
try fi (t1:ts1@(_:_)) ts2@[t2] = (ok t1 t2 $ fBase fi' updTy (tbroutRes t1) (tbroutRes t2)) ++ try fi' ts1 ts2
where fi' = trfiAdd (tbroutTracePPL t1) fi
try fi [t1] [t2] = ok t1 t2 $ fBase fi' updTy (tbroutRes t1) (tbroutRes t2)
where fi' = fi
-- check for a valid combi using lookahead info of next expansion
ok e1 e2 f | betaRedIsOkFitsinCombi (fiAllowTyVarBind fi)
e1 e2 = [f]
| otherwise = []
%%]
%%[(11 hmtyinfer)
varMayFit isL fi t@(Ty_Var v f)
= f `elem` fioBindCategs (fiFIOpts fi) && not (v `Set.member` fioDontBind (fiFIOpts fi))
-- where mbvs = if isL then fioBindLVars (fiFIOpts fi) else fioBindRVars (fiFIOpts fi)
%%]
%%[(9 hmtyinfer)
varMayExpand mbvs fi t@(Ty_Var v f)
= not ((fioBindIsYes mbvs || v `Set.member` fioBindNoSet mbvs) || v `Set.member` fioDontBind (fiFIOpts fi))
%%]
%%[(4 hmtyinfer).fitsIn.fVar
fVar' f fi updTy t1@(Ty_Var v1 f1) t2@(Ty_Var v2 f2)
| v1 == v2 && f1 == f2
%%[[8
&& not (fioExpandEqTyVar (fiFIOpts fi))
%%]]
= res fi t1
fVar' f fi updTy t1@(Ty_Var v1 f1) t2
| isJust mbTy1 = if fiVarIsExpandedL v1 fi
then errInfinite fi v1 t1'
else fVar' f (fiInhibitVarExpandL v1 fi2) updTy t1' t2
%%[[9
| varMayExpand mbvs fi t1 = fVar' f (fiInhibitBind v1 fi2) updTy t1 t2
%%]]
where mbTy1 = fiLookupTyVarCyc fi v1
t1' = fromJust mbTy1
%%[[4
fi2 = trfi "fVar L"
("t1:" >#< ppTyWithFI fi t1 >-< "t2:" >#< ppTyWithFI fi t2
%%[[9999
>-< "fioDontBind:" >#< show (fioDontBind (fiFIOpts fi)) >-< "fioBindNoSet:" >#< show (fioBindNoSet mbvs) >-< "fioBindIsYes:" >#< show (fioBindIsYes mbvs)
%%]]
) fi
%%][100
fi2 = fi
%%]]
%%[[9
mbvs = fioBindLVars (fiFIOpts fi)
%%]]
fVar' f fi updTy t1 t2@(Ty_Var v2 f2)
| isJust mbTy2 = if fiVarIsExpandedR v2 fi
then errInfinite fi v2 t2'
else fVar' f (fiInhibitVarExpandR v2 fi2) updTy t1 t2'
%%[[9
| varMayExpand mbvs fi t2 = fVar' f (fiInhibitBind v2 fi2) updTy t1 t2
%%]]
where mbTy2 = fiLookupTyVarCyc fi v2
t2' = fromJust mbTy2
%%[[4