@@ -11,6 +11,7 @@ import Idris.Core.TT
1111import Idris.Core.Evaluate
1212
1313import Control.Monad.State
14+import Control.Applicative
1415import Data.Maybe
1516import Debug.Trace
1617
@@ -44,13 +45,25 @@ partial_eval :: Context ->
4445 [(Name, Maybe Int)] ->
4546 [Either Term (Term, Term)] ->
4647 Maybe [Either Term (Term, Term)]
47−partial_eval ctxt ns tms = mapM peClause tms where
48+partial_eval ctxt ns_in tms = mapM peClause tms where
49+ ns = squash ns_in
50+ squash ((n, Just x) : ns)
51+ | Just (Just y) <- lookup n ns
52+ = squash ((n, Just (x + y)) : drop n ns)
53+ | otherwise = (n, Just x) : squash ns
54+ squash (n : ns) = n : squash ns
55+ squash [] = []
56+
57+ drop n ((m, _) : ns) | n == m = ns
58+ drop n (x : ns) = x : drop n ns
59+ drop n [] = []
60+
4861 -- If the term is not a clause, it is simply kept as is
4962 peClause (Left t) = Just $ Left t
5063 -- If the term is a clause, specialise the right hand side
5164 peClause (Right (lhs, rhs))
5265 = let (rhs', reductions) = specialise ctxt [] (map toLimit ns) rhs in
53− do checkProgress ns reductions
66+ do when (length tms == 1) $ checkProgress ns reductions
5467 return (Right (lhs, rhs'))
5568
5669 toLimit (n, Nothing) = (n, 65536) -- somewhat arbitrary reduction limit
@@ -103,23 +116,37 @@ specType args ty = let (t, args') = runState (unifyEq args ty) [] in
103116 put (args ++ (zip xs (repeat (sUN "_"))))
104117 return t
105118
106−-- | Creates an Idris type declaration given current state and a specialised TT function application type.
119+-- | Creates an Idris type declaration given current state and a
120+-- specialised TT function application type.
107121-- Can be used in combination with the output of 'specType'.
122+--
123+-- This should: specialise any static argument position, then generalise
124+-- over any function applications in the result.
108125mkPE_TyDecl :: IState -> [(PEArgType, Term)] -> Type -> PTerm
109126mkPE_TyDecl ist args ty = mkty args ty
110127 where
111128 mkty ((ExplicitD, v) : xs) (Bind n (Pi t k) sc)
112− = PPi expl n (delab ist t) (mkty xs sc)
129+ = PPi expl n (delab ist (generaliseIn t)) (mkty xs sc)
113130 mkty ((ImplicitD, v) : xs) (Bind n (Pi t k) sc)
114131 | concreteClass ist t = mkty xs sc
115132 | classConstraint ist t
116− = PPi constraint n (delab ist t) (mkty xs sc)
117− | otherwise = PPi impl n (delab ist t) (mkty xs sc)
133+ = PPi constraint n (delab ist (generaliseIn t)) (mkty xs sc)
134+ | otherwise = PPi impl n (delab ist (generaliseIn t)) (mkty xs sc)
118135
119136 mkty (_ : xs) t
120137 = mkty xs t
121138 mkty [] t = delab ist t
122139
140+ generaliseIn tm = evalState (gen tm) 0
141+
142+ gen tm | (P _ fn _, args) <- unApply tm,
143+ isFnName fn (tt_ctxt ist)
144+ = do nm <- get
145+ put (nm + 1)
146+ return (P Bound (sMN nm "spec") Erased)
147+ gen (App f a) = App <$> gen f <*> gen a
148+ gen tm = return tm
149+
123150-- | Checks if a given argument is a type class constraint argument
124151classConstraint :: Idris.AbsSyntax.IState -> TT Name -> Bool
125152classConstraint ist v
@@ -265,9 +292,9 @@ getSpecApps ist env tm = ga env (explicitNames tm) where
265292 ga env tm@(App f a) | (P _ n _, args) <- unApply tm,
266293 n `notElem` map fst (idris_metavars ist) =
267294 ga env f ++ ga env a ++
268− case (lookupCtxt n (idris_statics ist),
269− lookupCtxt n (idris_implicits ist)) of
270− ([statics], [imps]) ->
295+ case (lookupCtxtExact n (idris_statics ist),
296+ lookupCtxtExact n (idris_implicits ist)) of
297+ (Just statics, Just imps) ->
271298 if (length statics == length args && or statics) then
272299 case buildApp env statics imps args [0..] of
273300 args -> [(n, args)]