33 | %language ElabReflection
37 | ---------------------------------
38 | --- SPECIALISATION ERROR TYPE ---
39 | ---------------------------------
41 | ||| Specialisation error
42 | export
44 | ||| Failed to extract polymorphic type name from task
46 | ||| Unused variable
48 | ||| Partial specification
50 | ||| Internal error
52 | ||| Lambda has unnamed arguments
54 | ||| Polymorphic type has unnamed arguments
56 | ||| Failed to get TypeInfo
57 | |||
58 | ||| Can occur either due to trying to specialise a non-type invocation
59 | ||| or due to not having the necessary TypeInfo in the NamesInfoInTypes instance
62 | %hint
63 | export
67 | --------------------------------
68 | --- SPECIALISATION TASK TYPE ---
69 | --------------------------------
71 | ||| Specialisation task
74 | ||| Full unification task
78 | ||| Unification task type
81 | ||| Namespace in which specialiseData was called
83 | ||| Name of specialised type
85 | ||| Invocation of polymorphic type extracted from unification task
87 | ||| Invocation of specialised type given default arguents
89 | ||| Polymorphic type's TypeInfo
91 | ||| Proof that all the constructors of the polymorphic type are named
105 | ]
107 | ||| Unification results for the whole type
111 | ------------------------
112 | --- HELPER FUNCTIONS ---
113 | ------------------------
117 | [noHints]
122 | %defaulthint
126 | }
133 | export
137 | export
141 | export
142 | %defaulthint
154 | ||| Prepend namespace into which everything is generated to name
158 | ||| Given a sequence of arguments, return list of argument name-BindVar pairs
162 | ||| Given a list of arguments and a list of their aliases, apply aliases to then
176 | Element
183 | ||| Given a list of arguments, generate a list of aliased arguments
184 | ||| and a list of aliases
191 | let aliases = pushIn as %search <&> \(x `Element` xN) => (argName x, f $ Expr.argName x @{xN})
194 | ||| Make an argument omega implicit if it is explicit
198 | ||| Make an argument omega implicit
202 | ||| Make a type argument zero-count
206 | ||| A tuple value of multiple repeating expressions
212 | ||| Assemble a TTImp of a tuple from a list of `TTImp`s
218 | ||| Proof that hideExplicitArg doesn't affect namedness of arguments
228 | ||| Proof that makeImplicit doesn't affect namedness of arguments
234 | makeImplicitPreservesNames (x :: xs) @{_ :: _} with (x) -- This `with` match is a workaround for coverage checking bug
238 | ||| Make all explicit arguments in list implicit
239 | hideExplicitArgs : (xs : List Arg) -> (0 _ : All IsNamedArg xs) => Subset (List Arg) (All IsNamedArg)
242 | ||| Make all arguments in list implicit
243 | makeArgsImplicit : (xs : List Arg) -> (0 _ : All IsNamedArg xs) => Subset (List Arg) (All IsNamedArg)
246 | ---------------------
247 | --- TASK ANALYSIS ---
248 | ---------------------
250 | ||| Given a list of arguments and a sorted set of names,
251 | ||| assert that every argument's name is in that set
261 | ||| Remove named and auto-implicit applications of holes
267 | ||| Generate an AnyApp for given Arg, with the argument value either
268 | ||| retrieved from the map if present or generated with `fallback`
274 | AnyApp
278 | ||| Generate a List AnyApp for given argument List,
279 | ||| with arguments retrieved from the map if present or generated with `fallback`
291 | ||| Get all the information needed for specialisation from task
303 | -- Check for unused arguments
305 | -- Extract name of polymorphic type
308 | -- Prove that all spec lambda arguments are named
311 | -- Create aliases for spec lambda's arguments and perform substitution
312 | let (Element tqArgs tqArgsNamed, tqAlias) = transformArgNames (prependS "fv^\{resultName}^") tqArgs
315 | -- Check for partial application in spec
318 | -- Prove that all spec lambda type's arguments are named
321 | -- Apply aliasing to spec lambda type's info
323 | -- Get current namespace
325 | -- Get polymorphic type's info
328 | -- Prove all its arguments/constructors/constructor arguments are named
346 | }
349 | ||| Returns a full application of the given type constructor
350 | ||| with argument values sourced from `argValues`
351 | ||| or generated with `fallback` if not present
352 | export
358 | TTImp
363 | ||| Returns a full application of the given constructor
364 | ||| with argument values sourced from `argValues`
365 | ||| or generated with `fallback` if not present
366 | export
372 | TTImp
376 | ||| Proof that Vect.All works over Vect.snoc
377 | export
382 | ||| List + List.All to Vect + Vect.All
383 | export
391 | ||| Proof that List.All works over List.snoc
392 | export
398 | ||| SnocList + SnocList.All to List + List.All
399 | export
406 | ||| Internal state of recursion search algorithm
409 | ||| Accumulated transformation to cast from argument type to specialised type
411 | ||| Accumulated transformation to cast from specialised type to argument type
413 | ||| SnocList containing recursiveness of previous arguments
415 | ||| The pre-baked arguments to run unification with.
417 | ||| Accumulated arguments to be used in specialised constructor
420 | ||| Specialistaion-related constructor argument metadata
423 | ||| The argument's type can be substituted by specialised type invocation
426 | ||| Specialisation-related constructor metadata
429 | ||| Metadata for each argument
431 | ||| Replacements to transform original argument's type to specialised type
433 | ||| Replacement to transform specialised type to original argument's type
447 | ||| Specialisation-related type metadata
450 | ||| Specialisation-related metadata for each constructor
453 | ||| Generate a constructor binding where only recursive arguments are bound.
454 | ||| Said arguments are also aliased via `alias` function.
458 | where
467 | ---------------------------
468 | --- CONSTRUCTOR MAPPING ---
469 | ---------------------------
470 | ||| Run monadic operation on all constructors of specialised type
480 | ||| Map over all constructors for which unification succeeded
497 | ||| Run monadic operation on all pairs of specified and polymorphic constructors
518 | where
532 | -------------------------------
533 | --- CONSTRUCTOR UNIFICATION ---
534 | -------------------------------
536 | ||| Run unification for a given polymorphic constructor
537 | unifyCon : MonadLog m => (unifier : CanUnify m) => (con : Con) -> (0 conN : ConArgsNamed con) => m UnificationVerdict
544 | logPoint DetailedDebug "specialiseData.unifyCon" [t.polyTy, con] "Unifier task: \{show uniTask}"
546 | logValue DetailedDebug "specialiseData.unifyCon" [t.polyTy, con] "Unifier output: \{show uniRes}" uniRes
548 | ---------------------------------
549 | --- SPECIFIED TYPE GENERATION ---
550 | ---------------------------------
552 | ||| Generate argument of a specified constructor
558 | let piInfo = if fromLambda && (fvData.piInfo == ExplicitArg) then ImplicitArg else fvData.piInfo
565 | ||| Check if a given argument is "recursive" (i.e. its type can be replaced with invocation of specialised type)
581 | pure $
582 | MkRSS
583 | cRenames
584 | pToMRenames
603 | pure $
604 | MkRSS
615 | pure $
616 | MkRSS
617 | cRenames
618 | pToMRenames
623 | ||| Generate a specialised constructor
643 | let n = if params.eraseConNames then fromString "\{t.resultName}^Con^\{show cIdx}" else dropNS pCon.name
644 | rssRhs <- foldlM checkArgRecursion (MkRSS empty empty [<] (Element [] []) (Element [<] [<])) specArgs
645 | let (MkRSS mToPRenames pToMRenames argsAreRecursive' _ (Element outArgs' outArgsNamed')) = rssRhs
654 | ||| Generate a specialised type
674 | ------------------------
675 | --- CLAIM DERIVATION ---
676 | ------------------------
677 | ||| Generate IPi with implicit type arguments and given return
686 | ||| Generate specialised to polimorphic type conversion function signature
688 | mkMToPImplClaim = public' "mToPImpl" $ forallMTArgs $ arg t.specInvocation .-> t.fullInvocation
690 | ||| Generate specialised to polimorphic cast signature
692 | mkMToPClaim = interfaceHint Public "mToP" $ forallMTArgs $ `(Cast ~(t.specInvocation) ~(t.fullInvocation))
694 | ||| Decidable equality signatures
699 | piAll
704 | ]
707 | mkDecEqClaim = interfaceHint Public "decEq'" $ forallMTArgs `(DecEq ~(t.fullInvocation) => DecEq ~(t.specInvocation))
712 | forallMTArgs
715 | forallMTArgs
719 | ]
730 | ]
732 | ||| Generate specialised to polymorphic type conversion function signature
734 | mkPToMImplClaim = public' "pToMImpl" $ forallMTArgs $ arg t.fullInvocation .-> t.specInvocation
736 | ||| Generate specialised to polimorphic cast signature
745 | forallMTArgs
749 | ]
755 | forallMTArgs
758 | forallMTArgs
761 | forallMTArgs
765 | ]
776 | ]
785 | ]
787 | ------------------------------------
788 | --- POLY TO POLY CAST DERIVATION ---
789 | ------------------------------------
793 | transMachineVars $ IBindVar fc n@(MN ns nn) = IBindVar fc $ fromString "MS^\{show ns}^\{show nn}"
797 | ||| Generate specialised to polymorphic type conversion function clause
798 | ||| for given constructor
809 | Clause
818 | ||| Generate specialised to polymorphic type conversion function declarations
828 | ]
830 | ||| Generate specialised to polymorphic cast signature
835 | ||| Generate specialised to polymorphic cast declarations
839 | ]
841 | -----------------------------------
842 | --- CAST INJECTIVITY DERIVATION ---
843 | -----------------------------------
845 | ||| Emit a recursive call to castInjImpl constructing the proof from given names
849 | ||| Generate a with-clause corresponding to a single recursive argument
859 | ]
861 | ||| Wrap a term into a number of `IAppWith`s with underscores
866 | ||| Generate a final with-clause that matches all equality proofs to `Refl`s
877 | ]
879 | ||| Generate a left-hand-side for recursive argument with-clauses
886 | ||| Wrap a clause in with-clauses for all given names
889 | mkRecArgClauses (x :: xs) exLhs inner = mkArgWithClause x exLhs $ mkRecArgClauses xs `(~exLhs | _ | _) inner
891 | ||| Derive a single cast injectivity clause
902 | Clause
907 | (var "castInjImpl") .! ("castInj^x", emptyCon) .! ("castInj^y", emptyCon) .$ `(Refl) .= `(Refl)
914 | ||| Derive cast injectivity proof
932 | ~=~
942 | ]
944 | -------------------------------------
945 | --- DECIDABLE EQUALITY DERIVATION ---
946 | -------------------------------------
948 | ||| Decidable equality clause
953 | .=
961 | ||| Derive decidable equality
971 | ]
973 | -----------------------
974 | --- SHOW DERIVATION ---
975 | -----------------------
977 | ||| Derive Show implementation via cast
989 | ]
991 | ---------------------
992 | --- EQ DERIVATION ---
993 | ---------------------
995 | ||| Derive Eq implementation via cast
1006 | ]
1008 | ------------------------------------
1009 | --- POLY TO POLY CAST DERIVATION ---
1010 | ------------------------------------
1012 | ||| Generate specialised to polymorphic type conversion function signature
1017 | TTImp
1021 | ||| Generate specialised to polymorphic type conversion function clause
1022 | ||| for given constructor
1033 | Clause
1041 | ||| Generate specialised to polymorphic type conversion function declarations
1051 | ]
1053 | ||| Generate specialised to polymorphic cast signature
1058 | ||| Generate specialised to polymorphic cast declarations
1062 | ]
1064 | -----------------------------
1065 | --- FROMSTRING DERIVATION ---
1066 | -----------------------------
1078 | ]
1080 | ----------------------
1081 | --- NUM DERIVATION ---
1082 | ----------------------
1099 | `(MkNum
1103 | ]
1104 | ]
1106 | ------------------------------------
1107 | --- SPECIALISED TYPE DECLARATION ---
1108 | ------------------------------------
1113 | where
1118 | ||| Generate declarations for given task, unification results, and specialised type
1119 | specDecls : MonadLog m => UniResults -> (mt : TypeInfo) -> (0 _ : AllTyArgsNamed mt) => TypeMeta -> m $ List Decl
1157 | logPoint DetailedDebug "specialiseData.specDecls.fromString.sig" [specTy] $ show fromStringClaims
1171 | ]
1178 | ]
1186 | ]
1193 | join
1204 | ]
1206 | ---------------------------
1207 | --- DATA SPECIALISATION ---
1208 | ---------------------------
1210 | ||| Perform a specialisation for a given type name, kind and content expressions
1211 | |||
1212 | ||| In order to generate a specialised type declaration equivalent to the following type alias:
1213 | ||| ```
1214 | ||| VF : Nat -> Type
1215 | ||| VF n = Fin n
1216 | ||| ```
1217 | ||| ...you may use this function as follows:
1218 | ||| ```
1219 | ||| specialiseDataRaw `{VF} `(Nat -> Type) `(\n => Fin n)
1220 | ||| ```
1221 | export
1282 | unMkDPair (IApp _ (IApp _ (INamedApp _ (INamedApp _ (IVar _ "Builtin.DPair.MkDPair") _ _) _ _) dl) dr) =
1293 | where
1304 | export
1316 | export
1332 | ||| Perform a specialisation for a given type name and content lambda
1333 | |||
1334 | ||| In order to generate a specialised type declaration equivalent to the following type alias:
1335 | ||| ```
1336 | ||| VF : Nat -> Type
1337 | ||| VF n = Fin n
1338 | ||| ```
1339 | ||| ...you may use this function as follows:
1340 | ||| ```
1341 | ||| specialiseData `{VF} $ \n => Fin n
1342 | ||| ```
1343 | export
1345 | -- TaskLambda taskT =>
1357 | -- Quote spec lambda type
1359 | -- Quote spec lambda
1364 | ||| Perform a specialisation for a given type name and content lambda,
1365 | ||| returning a list of declarations and failing on error
1366 | |||
1367 | ||| In order to generate a specialised type declaration equivalent to the following type alias:
1368 | ||| ```
1369 | ||| VF : Nat -> Type
1370 | ||| VF n = Fin n
1371 | ||| ```
1372 | ||| ...you may use this function as follows:
1373 | ||| ```
1374 | ||| specialiseDataLam'' `{VF} $ \n => Fin n
1375 | ||| ```
1376 | export
1382 | -- TaskLambda taskT =>
1395 | ||| Perform a specialisation for a given type name and content lambda,
1396 | ||| declaring the results and failing on error
1397 | |||
1398 | ||| In order to declare a specialised type declaration equivalent to the following type alias:
1399 | ||| ```
1400 | ||| VF : Nat -> Type
1401 | ||| VF n = Fin n
1402 | ||| ```
1403 | ||| ...you may use this function as follows:
1404 | ||| ```
1405 | ||| %runElab specialiseDataLam' `{VF} $ \n => Fin n
1406 | ||| ```
1407 | export
1413 | -- TaskLambda taskT =>