module DDC.Core.Check.Judge.Sub
( makeSub)
where
import DDC.Type.Transform.SubstituteT
import DDC.Core.Exp.Annot.AnTEC
import DDC.Core.Check.Judge.Eq
import DDC.Core.Check.Judge.Inst
import DDC.Core.Check.Base
makeSub :: (Eq n, Ord n, Show n, Pretty n)
=> Config n
-> a
-> Context n
-> Exp (AnTEC a n) n
-> Type n
-> Type n
-> Error a n
-> CheckM a n
( Exp (AnTEC a n) n
, Context n)
makeSub config a ctx0 xL tL tR err
| TCon tc1 <- tL
, TCon tc2 <- tR
, equivTyCon tc1 tc2
= do
ctrace $ vcat
[ text "** SubCon"
, text " xL: " <> ppr xL
, text " tL: " <> ppr tL
, text " tR: " <> ppr tR
, indent 4 $ ppr ctx0
, empty ]
return (xL, ctx0)
| TVar u1 <- tL
, TVar u2 <- tR
, u1 == u2
= do
ctrace $ vcat
[ text "** SubVar"
, text " xL: " <> ppr xL
, text " tL: " <> ppr tL
, text " tR: " <> ppr tR
, indent 4 $ ppr ctx0
, empty ]
return (xL, ctx0)
| Just iL <- takeExists tL
, Just iR <- takeExists tR
, iL == iR
= do
ctrace $ vcat
[ text "** SubExVar"
, text " xL: " <> ppr xL
, text " tL: " <> ppr tL
, text " tR: " <> ppr tR
, indent 4 $ ppr ctx0
, empty ]
return (xL, ctx0)
| equivT tL tR
= do
ctrace $ vcat
[ text "** SubEquiv"
, text " xL: " <> ppr xL
, text " tL: " <> ppr tL
, text " tR: " <> ppr tR
, indent 4 $ ppr ctx0
, empty ]
return (xL, ctx0)
| isTExists tL
= do ctx1 <- makeInst config a ctx0 tR tL err
ctrace $ vcat
[ text "** SubInstL"
, text " xL: " <> ppr xL
, text " tL: " <> ppr tL
, text " tR: " <> ppr tR
, indent 4 $ ppr ctx0
, indent 4 $ ppr ctx1
, empty ]
return (xL, ctx1)
| isTExists tR
= do ctx1 <- makeInst config a ctx0 tL tR err
ctrace $ vcat
[ text "** SubInstR"
, text " xL: " <> ppr xL
, text " tL: " <> ppr tL
, text " tR: " <> ppr tR
, indent 4 $ ppr ctx0
, indent 4 $ ppr ctx1
, empty ]
return (xL, ctx1)
| Just (tL1, tL2) <- takeTFun tL
, Just (tR1, tR2) <- takeTFun tR
= do
ctrace $ vcat
[ text "*> SubArr"
, empty ]
(_, ctx1) <- makeSub config a ctx0 xL tR1 tL1 err
tL2' <- applyContext ctx1 tL2
tR2' <- applyContext ctx1 tR2
(_, ctx2) <- makeSub config a ctx1 xL tL2' tR2' err
ctrace $ vcat
[ text "*< SubArr"
, text " xL: " <> ppr xL
, text " tL: " <> ppr tL
, text " tR: " <> ppr tR
, indent 4 $ ppr ctx0
, indent 4 $ ppr ctx1
, indent 4 $ ppr ctx2
, empty ]
return (xL, ctx2)
| TApp tL1 tL2 <- tL
, TApp tR1 tR2 <- tR
= do
ctrace $ vcat
[ text "*> SubApp"
, empty ]
ctx1 <- makeEq config a ctx0 tL1 tR1 err
tL2' <- applyContext ctx1 tL2
tR2' <- applyContext ctx1 tR2
ctx2 <- makeEq config a ctx1 tL2' tR2' err
ctrace $ vcat
[ text "*< SubApp"
, text " xL: " <> ppr xL
, text " tL: " <> ppr tL
, text " tR: " <> ppr tR
, indent 4 $ ppr ctx0
, indent 4 $ ppr ctx1
, indent 4 $ ppr ctx2
, empty ]
return (xL, ctx2)
| TForall b t1 <- tL
= do
ctrace $ vcat
[ text "*> SubForall"
, empty ]
iA <- newExists (typeOfBind b)
let tA = typeOfExists iA
let t1' = substituteT b tA t1
let (ctx1, pos1) = markContext ctx0
let ctx2 = pushExists iA ctx1
let AnTEC _ e0 c0 _
= annotOfExp xL
let aFn = AnTEC t1' (substituteT b tA e0) (substituteT b tA c0) a
let aArg = AnTEC (typeOfBind b) (tBot kEffect) (tBot kClosure) a
let xL1 = XApp aFn xL (XType aArg tA)
(xL2, ctx3) <- makeSub config a ctx2 xL1 t1' tR err
let ctx4 = popToPos pos1 ctx3
ctrace $ vcat
[ text "*< SubForall"
, text " xL: " <> ppr xL
, text " LEFT: " <> ppr tL
, text " RIGHT: " <> ppr tR
, text " xL2: " <> ppr xL2
, indent 4 $ ppr ctx0
, indent 4 $ ppr ctx4
, empty ]
return (xL2, ctx4)
| otherwise
= do ctrace $ vcat
[ text "DDC.Core.Check.Exp.Inst.makeSub: no match"
, text " LEFT: " <> ppr tL
, text " RIGHT: " <> ppr tR ]
throw err