0 | module Deriving.DepTyCheck.Util.Specialisation
2 | import public Control.Monad.Either
4 | import public Data.DPair
5 | import public Data.List.Ex
6 | import public Data.List.Map
7 | import public Data.SortedMap
8 | import public Data.SortedMap.Extra
9 | import public Data.SortedSet
11 | import public Deriving.DepTyCheck.Gen.ForOneType.Interface
13 | import public Deriving.SpecialiseData
14 | import public Deriving.SpecialiseData.TaskFormation
16 | import public Language.Reflection.Unify
18 | import public Data.Hashable
19 | import public Data.Hashable.Base
24 | (.isPassthrough) : Elaboration m => GenArg -> m Bool
25 | (.isPassthrough) (MkGenArg a Nothing) = pure True
26 | (.isPassthrough) (MkGenArg a $
Just g) = do
27 | let True = snd (unPi a.type) == `(Type)
42 | (sig : GenSignature) ->
43 | List (Fin sig.targetType.args.length, Arg) ->
44 | List (Fin sig.targetType.args.length, TTImp) ->
46 | mkArgs sig [] _ = []
47 | mkArgs sig ((_, x) :: xs) [] = MkGenArg x Nothing :: mkArgs sig xs []
48 | mkArgs sig ((i1, x) :: xs) g@((i2, y) :: ys) =
50 | then MkGenArg x (Just y) :: mkArgs sig xs ys
51 | else MkGenArg x Nothing :: mkArgs sig xs g
58 | formGivenVals : (s : SortedSet _) -> List TTImp -> Vect s.size TTImp
59 | formGivenVals a b = fgvImpl (Vect.fromList $
Prelude.toList a) b
61 | fgvImpl : Vect l _ -> List TTImp -> Vect l TTImp
63 | fgvImpl (_ :: xs) [] = `(_) :: fgvImpl xs []
64 | fgvImpl (x :: xs) (y :: ys) = y :: fgvImpl xs ys
66 | genGivens : List (TTImp, Fin x, Arg) -> (s : SortedSet (Fin x) ** Vect s.size TTImp)
68 | let (l1, l2, l3) = unzip3 l
69 | let s = SortedSet.fromList l2
70 | let gv = formGivenVals s l1
74 | specTaskToName : Monad m => TTImp -> m Name
75 | specTaskToName t = do
76 | let (_, lamBody) = unLambda t
77 | let (callee, _) = unAppAny lamBody
80 | (IVar _ n) => show $
snd $
unNS n
82 | hash <- pure $
show $
hash t
83 | pure $
fromString "\{vname}^\{hash}.\{vname}^\{hash}"
85 | nameUnambigAndVis : Elaboration m => Name -> m Bool
86 | nameUnambigAndVis n = do
88 | _ : Unit <- check `(let x = ~(var n) in ()
)
89 | pure True) (pure False)
91 | allConstructorsVisible : Elaboration m => TypeInfo -> m Bool
92 | allConstructorsVisible ti = do
93 | all id <$> traverse (nameUnambigAndVis . name) ti.cons
95 | mkDPairOfUnknowns : Nat -> (Name -> TTImp) -> TTImp -> TTImp
96 | mkDPairOfUnknowns 0 _ t = t
97 | mkDPairOfUnknowns (S n) helper t = do
98 | let nn = fromString $
"dph^\{show n}"
99 | `(MkDPair
~(helper nn) ~(mkDPairOfUnknowns n helper t))
101 | dPairOfUnknowns : Nat -> TTImp
102 | dPairOfUnknowns 0 = `(?
)
103 | dPairOfUnknowns (S n) = `(DPair ? $
\_ => ~(dPairOfUnknowns n))
105 | inSameNS : (nsSource: Name) -> Name -> Name
106 | inSameNS (NS ns _) n = NS ns n
110 | specialiseIfNeeded :
112 | NamesInfoInTypes =>
114 | DerivationClosure m =>
115 | (sig : GenSignature) ->
117 | Vect sig.givenParams.size TTImp ->
119 | specialiseIfNeeded sig fuel givenParamValues = do
120 | logPoint DetailedDebug "deptycheck.derive.specialisation" [sig] "Checking specialisation need for \{show givenParamValues}..."
122 | let True = any (\a => snd (unPi a.type) == `(Type)) $
index' sig.targetType.args <$> Prelude.toList sig.givenParams
124 | logValue DetailedDebug "deptycheck.derive.specialisation" [sig]
125 | "Not found any given type args, specialisation not needed."
128 | True <- allConstructorsVisible sig.targetType
130 | logValue DetailedDebug "deptycheck.derive.specialisation" [sig]
131 | "\{sig.targetType.name} has invisible constructors, specialisation impossible."
134 | let givenIdxVals = Prelude.toList sig.givenParams `zipV` givenParamValues
135 | let genArgs = mkArgs sig (withIndex sig.targetType.args) givenIdxVals
139 | False <- all id <$> traverse (.isPassthrough) genArgs
141 | logValue DetailedDebug "deptycheck.derive.specialisation" [sig]
142 | "Not found any type arguments that can be specialised upon, specialisation impossible."
145 | (lambdaRet, fvArgs, givenSubst) <- argsToSpecTask specDecideArg sig.targetType.name genArgs
146 | let preNorm = foldr lam lambdaRet fvArgs
147 | logPoint DetailedDebug "deptycheck.derive.specialisation" [sig] "Task before normalisation: \{show preNorm}"
149 | (lambdaTy, lambdaBody) <- normaliseTask fvArgs lambdaRet
150 | logPoint DetailedDebug "deptycheck.derive.specialisation" [sig] "NormaliseTask returned: lambdaTy = \{show lambdaTy};"
151 | logPoint DetailedDebug "deptycheck.derive.specialisation" [sig] " lambdaBody = \{show lambdaBody};"
153 | specName <- specTaskToName lambdaBody
154 | logPoint DetailedDebug "deptycheck.derive.specialisation" [sig] "Specialised type name: \{show specName}"
156 | (specTy, specDecls) : (TypeInfo, List Decl) <- case lookupType specName of
159 | info <- try (Just <$> getInfo' specName) (pure Nothing)
163 | logPoint DetailedDebug "deptycheck.derive.specialisation" [sig] "Specialised type not found, deriving..."
165 | NS nsn _ <- inCurrentNS ""
166 | | _ => fail "Internal error: inCurrentNS did not return NS"
168 | Right (specTy, specDecls) <- runEitherT {m} {e=SpecialisationError} $
169 | specialiseDataRaw {nsProvider = inNS thisNS} specName lambdaTy lambdaBody
170 | | Left err => fail "INTERNAL ERROR: Specialisation \{show lambdaBody} failed with error \{show err}."
171 | logPoint DetailedDebug "deptycheck.derive.specialisation" [sig] "Derived \{show specTy.name}"
174 | specTy <- getInfo' specName
175 | logValue Trace "deptycheck.derive.specialisation" [sig]
176 | "Declared specialised type \{show specTy.name}: \{show lambdaRet}"
179 | logValue DetailedDebug "deptycheck.derive.specialisation" [sig]
180 | "Found \{show specTy.name}"
183 | logValue DetailedDebug "deptycheck.derive.specialisation" [sig]
184 | "Found \{show specTy.name}"
187 | let Yes stNamed = areAllTyArgsNamed specTy
188 | | No _ => fail "INTERNAL ERROR: Specialised type \{show specTy.name} does not have fully named arguments and constructors."
190 | let (
newGP ** newGVals)
= genGivens $
mapMaybe (\(a,b) => map (,b) a) $
zip givenSubst $
withIndex specTy.args
192 | (inv, cg_rhs) <- callGen (MkGenSignature specTy newGP) fuel newGVals
193 | let inv : TTImp = case cg_rhs of
195 | Just (
n ** perm)
=> reorderGend False perm inv
197 | let generateds = sig.targetType.args.length `minus` sig.givenParams.size
200 | then `(map
(cast
@{~(var $
inSameNS specTy.name "mToP")}) $
~inv)
202 | `(the
(Gen MaybeEmpty
~(dPairOfUnknowns generateds)) $ map
(\invv =>
204 | ~(mkDPairOfUnknowns generateds bindVar (bindVar "inv")) =>
205 | ~(mkDPairOfUnknowns generateds var `(cast
@{~(var $
inSameNS specTy.name "mToP")} inv
))) ~inv)