13 | module Derive.Refined
15 | import public Data.Refined
16 | import Language.Reflection.Util
28 | data AppVar : (arg : PArg n) -> (nm : Name) -> Type where
32 | -> (0 prf : (n1 == n2) === True)
33 | -> AppVar (PApp p (PVar n2)) n1
36 | {0 n1, n2, n3 : Name}
38 | -> (0 prf : (n1 == n2) === True)
39 | -> AppVar (PNamedApp p n3 (PVar n2)) n1
43 | -> {0 p, p2 : PArg n}
45 | -> AppVar (PApp p p2) n1
49 | -> {0 p, p2 : PArg n}
51 | -> AppVar (PNamedApp p n2 p2) n1
55 | appVar : (nm : Name) -> (arg : PArg n) -> Maybe (AppVar arg nm)
56 | appVar nm (PApp p (PVar n2)) with (nm == n2) proof eq
57 | _ | True = Just (HereApp eq)
58 | _ | False = case appVar nm p of
59 | Just prf => Just (ThereApp prf)
61 | appVar nm (PApp p q) = case appVar nm p of
62 | Just prf => Just (ThereApp prf)
64 | appVar nm (PNamedApp p _ (PVar n2)) with (nm == n2) proof eq
65 | _ | True = Just (HereNamedApp eq)
66 | _ | False = case appVar nm p of
67 | Just prf => Just (ThereNamedApp prf)
69 | appVar nm (PNamedApp p _ q) = case appVar nm p of
70 | Just prf => Just (ThereNamedApp prf)
72 | appVar n1 _ = Nothing
77 | data ProofInfo : PiInfo TTImp -> Type where
78 | PIAuto : ProofInfo AutoImplicit
79 | PIExplicit : ProofInfo ExplicitArg
83 | proofInfo : (pi : PiInfo TTImp) -> Maybe (ProofInfo pi)
84 | proofInfo ExplicitArg = Just PIExplicit
85 | proofInfo AutoImplicit = Just PIAuto
86 | proofInfo _ = Nothing
93 | data RefinedArgs : (args : Vect m (ConArg n)) -> Type where
96 | -> {0 t1,t2 : PArg n}
97 | -> {0 mn : Maybe Name}
99 | -> {0 pi : PiInfo TTImp}
102 | -> RefinedArgs [CArg (Just nm) MW ExplicitArg t1 , CArg mn c pi t2]
109 | -> RefinedArgs (ParamArg ix t :: as)
114 | refinedArgs : (as : Vect m (ConArg n)) -> Maybe (RefinedArgs as)
115 | refinedArgs [CArg (Just n1) MW ExplicitArg _, CArg _ M0 pi t] =
116 | [| RArgs (proofInfo pi) (appVar n1 t) |]
117 | refinedArgs (ParamArg ix t :: as) = RImplicit <$> refinedArgs as
118 | refinedArgs _ = Nothing
128 | -> (as : Vect m (ConArg n))
131 | proofType ns (_ :: as) (RImplicit x) = proofType ns as x
132 | proofType ns [_, CArg _ _ _ t2] (RArgs x y) = `(\x => ~(fromApp t2 y))
135 | fromApp : (t : PArg n) -> AppVar t nm -> TTImp
136 | fromApp (PApp p _) (HereApp _) = `(~(ttimp ns p) x
)
137 | fromApp (PApp p t) (ThereApp q) = app (fromApp p q) (ttimp ns t)
138 | fromApp (PNamedApp p nm _) (HereNamedApp _) = namedApp (ttimp ns p) nm (varStr "x")
139 | fromApp (PNamedApp p nm t) (ThereNamedApp q) = namedApp (fromApp p q) nm (ttimp ns t)
144 | (as : Vect m (ConArg n))
147 | isErased (_ :: as) (RImplicit x) = isErased as x
148 | isErased [_, CArg _ M0 _ _] (RArgs x y) = True
149 | isErased [_, CArg _ _ _ _] (RArgs x y) = False
155 | -> (as : Vect m (ConArg n))
158 | valType ns [CArg _ _ _ t, _] (RArgs x y) = ttimp ns t
159 | valType ns (_ :: as) (RImplicit x) = valType ns as x
163 | valName : (as : Vect m (ConArg n)) -> RefinedArgs as -> Name
164 | valName [CArg (Just nm) _ _ t, _] (RArgs x y) = nm
165 | valName (_ :: as) (RImplicit x) = valName as x
175 | appCon : TTImp -> (c : ParamCon n) -> RefinedArgs c.args -> TTImp
176 | appCon t (MkParamCon cn _ as) x = fromArgs (var cn `app` t) as x
179 | fromArgs : TTImp -> (as : Vect k (ConArg n)) -> RefinedArgs as -> TTImp
180 | fromArgs s [_, CArg mn c ExplicitArg _] (RArgs x y) = `(~(s) prf
)
181 | fromArgs s [_, CArg mn c _ _] (RArgs x y) = `(~(s) @{prf
})
182 | fromArgs s (ParamArg _ _ :: as) (RImplicit x) = fromArgs s as x
189 | data RefinedInfo : ParamTypeInfo -> Type where
192 | -> RefinedArgs c.args
193 | -> RefinedInfo (MkParamTypeInfo ti p ns [c] s)
196 | refinedInfo : (p : ParamTypeInfo) -> Res (RefinedInfo p)
197 | refinedInfo (MkParamTypeInfo t _ _ [c] _) = case refinedArgs c.args of
198 | Just x => Right (RI x)
199 | Nothing => Left "\{t.name} is not a refinement type with an explicit or auto-implicit proof"
200 | refinedInfo p = Left "\{p.getName} is not a single-constructor data type"
205 | refineClaim : (fun : Name) -> (p : ParamTypeInfo) -> RefinedInfo p -> Decl
206 | refineClaim fun (MkParamTypeInfo ti p ns [c] s) (RI x) =
207 | let res := `(Maybe
~(ti.applied))
208 | vtpe := valType ns c.args x
209 | tpe := piAll `(~(vtpe) -> ~(res)) ti.implicits
213 | refineDef : (fun : Name) -> (p : ParamTypeInfo) -> RefinedInfo p -> Decl
214 | refineDef fun (MkParamTypeInfo ti p ns [c] s) (RI x) =
215 | let prf := proofType ns c.args x
217 | lhs := var fun `app` v
218 | rhs0 := `(case hdec0
{p = ~(proofType ns c.args x)} ~(v) of
219 | Just0 prf
=> Just $
~(appCon v c x)
220 | Nothing0
=> Nothing
)
221 | rhs := `(case hdec
{p = ~(proofType ns c.args x)} ~(v) of
222 | Just prf
=> Just $
~(appCon v c x)
223 | Nothing
=> Nothing
)
224 | in def fun [patClause lhs (if isErased c.args x then rhs0 else rhs)]
227 | refineTL : (fun : Name) -> (p : ParamTypeInfo) -> RefinedInfo p -> TopLevel
228 | refineTL fun p x = TL (refineClaim fun p x) (refineDef fun p x)
232 | -> (fun,constraint : Name)
234 | -> (p : ParamTypeInfo)
237 | litTL vis fun con tpe (MkParamTypeInfo ti q ns [c] s) (RI x) =
238 | let p := MkParamTypeInfo ti q ns [c] s
241 | res := appCon (var fun `app` varStr "n") c x
242 | in case isErased c.args x of
244 | let test := `(hdec
{p = ~(proofType ns c.args x)} (~(vfun) n
))
245 | pi := `((n : ~(tpe)) -> {auto 0 _ : IsJust
~(test)} -> ~(arg))
246 | tpe := piAll pi (allImplicits p con)
247 | rhs := `(let prf := fromJust
~(test) in ~(res))
248 | df := def fun [ patClause `(~(var fun) n
) rhs ]
249 | in TL (simpleClaim vis fun tpe) df
251 | let test := `(hdec0
{p = ~(proofType ns c.args x)} (~(vfun) n
))
252 | pi := `((n : ~(tpe)) -> {auto 0 _ : IsJust0
~(test)} -> ~(arg))
253 | tpe := piAll pi (allImplicits p con)
254 | rhs := `(let 0 prf := fromJust0
~(test) in ~(res))
255 | df := def fun [ patClause `(~(var fun) n
) rhs ]
256 | in TL (simpleClaim vis fun tpe) df
259 | fromIntTL : Visibility -> (p : ParamTypeInfo) -> RefinedInfo p -> TopLevel
260 | fromIntTL vis = litTL vis "fromInteger" "Num" `(Integer)
263 | fromDblTL : Visibility -> (p : ParamTypeInfo) -> RefinedInfo p -> TopLevel
264 | fromDblTL vis = litTL vis "fromDouble" "FromDouble" `(Double)
267 | fromStrTL : Visibility -> (p : ParamTypeInfo) -> RefinedInfo p -> TopLevel
268 | fromStrTL vis = litTL vis "fromString" "FromString" `(String)
275 | refineName : Named a => a -> Name
276 | refineName v = funName v "refine"
279 | Refined : List Name -> ParamTypeInfo -> Res (List TopLevel)
280 | Refined nms p = map (pure . refineTL (refineName p) p) $
refinedInfo p
283 | RefinedIntegerVis :
287 | -> Res (List TopLevel)
288 | RefinedIntegerVis vis nms p = map decls $
refinedInfo p
290 | decls : RefinedInfo p -> List TopLevel
292 | let fun := refineName p.getName
293 | in [ refineTL fun p x, fromIntTL vis p x ]
296 | RefinedInteger : List Name -> ParamTypeInfo -> Res (List TopLevel)
297 | RefinedInteger = RefinedIntegerVis Export
304 | -> Res (List TopLevel)
305 | RefinedDoubleVis vis nms p = map decls $
refinedInfo p
307 | decls : RefinedInfo p -> List TopLevel
309 | let fun := refineName p
310 | in [ refineTL fun p x, fromIntTL vis p x, fromDblTL vis p x ]
313 | RefinedDouble : List Name -> ParamTypeInfo -> Res (List TopLevel)
314 | RefinedDouble = RefinedDoubleVis Export
321 | -> Res (List TopLevel)
322 | RefinedStringVis vis nms p = map decls $
refinedInfo p
324 | decls : RefinedInfo p -> List TopLevel
326 | let fun := refineName p
327 | in [ refineTL fun p x, fromStrTL vis p x ]
330 | RefinedString : List Name -> ParamTypeInfo -> Res (List TopLevel)
331 | RefinedString = RefinedStringVis Export