module DDC.Core.Check.Judge.Inst
(makeInst)
where
import DDC.Core.Check.Base
makeInst :: (Eq n, Ord n, Pretty n)
=> Config n
-> a
-> Context n
-> Type n
-> Type n
-> Error a n
-> CheckM a n (Context n)
makeInst !config !a !ctx0 !tL !tR !err
| Just iL <- takeExists tL
, not $ isTExists tR
= do let Just ctx1 = updateExists [] iL tR ctx0
ctrace $ vcat
[ text "** InstLSolve"
, text " LEFT: " <> ppr tL
, text " RIGHT: " <> ppr tR
, indent 4 $ ppr ctx0
, indent 4 $ ppr ctx1
, empty ]
return ctx1
| Just iL <- takeExists tL, Just lL <- locationOfExists iL ctx0
, Just iR <- takeExists tR, Just lR <- locationOfExists iR ctx0
, lL > lR
= do let Just ctx1 = updateExists [] iR tL ctx0
ctrace $ vcat
[ text "** InstLReach"
, text " LEFT: " <> ppr tL
, text " RIGHT: " <> ppr tR
, indent 4 $ ppr ctx0
, indent 4 $ ppr ctx1
, empty ]
return ctx1
| Just iL <- takeExists tL, Just lL <- locationOfExists iL ctx0
, Just iR <- takeExists tR, Just lR <- locationOfExists iR ctx0
, lR > lL
= do let Just ctx1 = updateExists [] iL tR ctx0
ctrace $ vcat
[ text "** InstRReach"
, text " LEFT: " <> ppr tL
, text " RIGHT: " <> ppr tR
, indent 4 $ ppr ctx0
, indent 4 $ ppr ctx1
, empty ]
return ctx1
| Just iL <- takeExists tL
, Just (tR1, tR2) <- takeTFun tR
= do
iL1 <- newExists kData
let tL1 = typeOfExists iL1
iL2 <- newExists kData
let tL2 = typeOfExists iL2
let Just ctx1 = updateExists [iL2, iL1] iL (tFun tL1 tL2) ctx0
ctx2 <- makeInst config a ctx1 tR1 tL1 err
tR2' <- applyContext ctx2 tR2
ctx3 <- makeInst config a ctx2 tL2 tR2' err
ctrace $ vcat
[ text "** InstLArr"
, text " LEFT: " <> ppr tL
, text " RIGHT: " <> ppr tR
, indent 4 $ ppr ctx0
, indent 4 $ ppr ctx3
, empty ]
return ctx3
| Just iR <- takeExists tR
, not $ isTExists tL
= do let Just ctx1 = updateExists [] iR tL ctx0
ctrace $ vcat
[ text "** InstRSolve"
, text " LEFT: " <> ppr tL
, text " RIGHT: " <> ppr tR
, indent 4 $ ppr ctx0
, indent 4 $ ppr ctx1
, empty ]
return ctx1
| Just (tL1, tL2) <- takeTFun tL
, Just iR <- takeExists tR
= do
iR1 <- newExists kData
let tR1 = typeOfExists iR1
iR2 <- newExists kData
let tR2 = typeOfExists iR2
let Just ctx1 = updateExists [iR2, iR1] iR (tFun tR1 tR2) ctx0
ctx2 <- makeInst config a ctx1 tR1 tL1 err
tL2' <- applyContext ctx2 tL2
ctx3 <- makeInst config a ctx2 tL2' tR2 err
ctrace $ vcat
[ text "** InstRArr"
, text " LEFT: " <> ppr tL
, text " RIGHT: " <> ppr tR
, indent 4 $ ppr ctx0
, indent 4 $ ppr ctx3
, empty ]
return ctx3
| otherwise
= do
ctrace $ vcat
[ text "DDC.Core.Check.Exp.Inst.inst: no match"
, text " LEFT: " <> ppr tL
, text " RIGHT: " <> ppr tR
, indent 2 $ ppr ctx0
, empty ]
throw err