on master help sign in
Clean up inference in Pruviloj

Now, the proper Infer type is used, and a tactic is exported.

commit210db7d66447248e8f689eada72cf127f8d4ea0b authorDavid Raymond Christiansen <david@davidchristiansen.dk> dateThu 1 Oct 2015, 16:59 (11 years ago) parent6ee21c7
2 files changed+32−18
libs/pruviloj/Pruviloj/Core.idr+27−9 libs/pruviloj/Pruviloj/Internals.idr+5−9
libs/pruviloj/Pruviloj/Core.idr+27−9
@@ -3,13 +3,8 @@
33||| eventual Prelude inclusion.
44module Pruviloj.Core
55
6−
7−import Language.Reflection.Elab
86import Language.Reflection.Utils
97
10−data Infer : Type where
11− MkInfer : (a : Type) -> a -> Infer
12−
138||| Run something for effects, throwing away the return value
149ignore : Functor f => f a -> f ()
1510ignore x = map (const ()) x
@@ -85,11 +80,11 @@ intros = do g <- snd <$> getGoal
8580
8681||| Run a tactic inside of a particular hole, if it still exists. If
8782||| it has been solved, do nothing.
88−inHole : TTName -> Elab () -> Elab ()
83+inHole : TTName -> Elab a -> Elab (Maybe a)
8984inHole h todo =
90− when (h `elem` !getHoles) $
91− do focus h
92− todo
85+ if (h `elem` !getHoles)
86+ then do focus h; Just <$> todo
87+ else return Nothing
9388
9489||| Restrict a polymorphic type to () for contexts where it doesn't
9590||| matter. This is nice for sticking `debug` in a context where
@@ -142,3 +137,26 @@ bindPat = do compute
142137 case g of
143138 Bind n (PVTy _) _ => patbind n
144139 _ => fail [TermPart g, TextPart "isn't looking for a pattern."]
140+
141+||| The underlying implementation type for the inferType operator.
142+data Infer : Type where
143+ MkInfer : (a : Type) -> a -> Infer
144+
145+||| Run a tactic script in a context where the type of the resulting
146+||| expression must be solvable via unification. Return the term and
147+||| its type.
148+|||
149+||| @ tac a tactic script that will be run with focus on the hole
150+||| whose type is to be inferred.
151+total
152+inferType : (tac : Elab ()) -> Elab (TT, TT)
153+inferType tac =
154+ case fst !(runElab `(Infer) (startInfer *> tac)) of
155+ `(MkInfer ~ty ~tm) => return (tm, ty)
156+ _ => fail [TextPart "Not infer"]
157+ where
158+ startInfer : Elab ()
159+ startInfer = do [_, (_, tmH)] <- apply (Var `{MkInfer}) [(True, 0), (False, 1)]
160+ | err => fail [TextPart "Type inference failure"]
161+ solve
162+ focus tmH
libs/pruviloj/Pruviloj/Internals.idr+5−9
@@ -77,10 +77,6 @@ enumerate xs = enumerate' xs 0
7777 enumerate' [] _ = []
7878 enumerate' (x::xs) n = (n, x) :: enumerate' xs (S n)
7979
80−getSigmaArgs : Raw -> Elab (Raw, Raw)
81−getSigmaArgs `(MkSigma {a=~_} {P=~_} ~rhsTy ~lhs) = return (rhsTy, lhs)
82−getSigmaArgs arg = fail [TextPart "Not a sigma constructor"]
83−
8480bindPats : List (TTName, Binder Raw) -> Raw -> Raw
8581bindPats [] res = res
8682bindPats ((n, b)::bs) res = RBind n (PVar (getBinderTy b)) $ bindPats bs res
@@ -109,19 +105,19 @@ partial
109105elabPatternClause : (lhs, rhs : Elab ()) -> Elab FunClause
110106elabPatternClause lhs rhs =
111107 do -- Elaborate the LHS in a context where its type will be solved via unification
112− (pat, _) <- runElab `(Sigma Type id) $
108+ (pat, _) <- runElab `(Infer) $
113109 do th <- newHole "finalTy" `(Type)
114110 patH <- newHole "pattern" (Var th)
115− fill `(MkSigma ~(Var th) ~(Var patH) : Sigma Type id)
111+ fill `(MkInfer ~(Var th) ~(Var patH))
116112 solve
117113 focus patH
118114 lhs
119115 -- Convert all remaining holes to pattern variables
120116 traverse_ {b=()} (\h => focus h *> patvar h) !getHoles
121− let (pvars, sigma) = extractBinders !(forgetTypes pat)
122− (rhsTy, lhsTm) <- getSigmaArgs sigma
117+ (pvars, `(MkInfer ~rhsTy ~lhsTm)) <- extractBinders <$> (forgetTypes pat)
118+ | fail [TextPart "Couldn't infer type of left-hand pattern"]
123119 rhsTm <- runElab (bindPatTys pvars rhsTy) $
124− do -- Introduce all the pattern variables from the LHS
120+ do -- Introduce all the pattern variables from the LHS
125121 repeatUntilFail bindPat <|> return ()
126122 rhs
127123 realRhs <- forgetTypes (fst rhsTm)