@@ -11,6 +11,7 @@ import Idris.Core.TT
11import Idris.Core.Evaluate
11import Idris.Core.Evaluate
13import Control.Monad.State
13import Control.Monad.State
14+import Control.Applicative
14import Data.Maybe
15import Data.Maybe
15import Debug.Trace
16import Debug.Trace
@@ -44,13 +45,25 @@ partial_eval :: Context ->
44 [(Name, Maybe Int)] ->
45 [(Name, Maybe Int)] ->
45 [Either Term (Term, Term)] ->
46 [Either Term (Term, Term)] ->
46 Maybe [Either Term (Term, Term)]
47 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
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
57+ drop n ((m, _) : ns) | n == m = ns
58+ drop n (x : ns) = x : drop n ns
48 -- If the term is not a clause, it is simply kept as is
61 -- If the term is not a clause, it is simply kept as is
49 peClause (Left t) = Just $ Left t
62 peClause (Left t) = Just $ Left t
50 -- If the term is a clause, specialise the right hand side
63 -- If the term is a clause, specialise the right hand side
51 peClause (Right (lhs, rhs))
64 peClause (Right (lhs, rhs))
52 = let (rhs', reductions) = specialise ctxt [] (map toLimit ns) rhs in
65 = let (rhs', reductions) = specialise ctxt [] (map toLimit ns) rhs in
53− do checkProgress ns reductions
66+ do when (length tms == 1) $ checkProgress ns reductions
54 return (Right (lhs, rhs'))
67 return (Right (lhs, rhs'))
56 toLimit (n, Nothing) = (n, 65536) -- somewhat arbitrary reduction limit
69 toLimit (n, Nothing) = (n, 65536) -- somewhat arbitrary reduction limit
@@ -103,23 +116,37 @@ specType args ty = let (t, args') = runState (unifyEq args ty) [] in
103 put (args ++ (zip xs (repeat (sUN "_"))))
116 put (args ++ (zip xs (repeat (sUN "_"))))
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.
107-- Can be used in combination with the output of 'specType'.
121-- Can be used in combination with the output of 'specType'.
123+-- This should: specialise any static argument position, then generalise
124+-- over any function applications in the result.
108mkPE_TyDecl :: IState -> [(PEArgType, Term)] -> Type -> PTerm
125mkPE_TyDecl :: IState -> [(PEArgType, Term)] -> Type -> PTerm
109mkPE_TyDecl ist args ty = mkty args ty
126mkPE_TyDecl ist args ty = mkty args ty
111 mkty ((ExplicitD, v) : xs) (Bind n (Pi t k) sc)
128 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)
113 mkty ((ImplicitD, v) : xs) (Bind n (Pi t k) sc)
130 mkty ((ImplicitD, v) : xs) (Bind n (Pi t k) sc)
114 | concreteClass ist t = mkty xs sc
131 | concreteClass ist t = mkty xs sc
115 | classConstraint ist t
132 | classConstraint ist t
116− = PPi constraint n (delab ist t) (mkty xs sc)
133+ = PPi constraint n (delab ist (generaliseIn t)) (mkty xs sc)
117− | otherwise = PPi impl n (delab ist t) (mkty xs sc)
134+ | otherwise = PPi impl n (delab ist (generaliseIn t)) (mkty xs sc)
119 mkty (_ : xs) t
136 mkty (_ : xs) t
120 = mkty xs t
137 = mkty xs t
121 mkty [] t = delab ist t
138 mkty [] t = delab ist t
140+ generaliseIn tm = evalState (gen tm) 0
142+ gen tm | (P _ fn _, args) <- unApply tm,
143+ isFnName fn (tt_ctxt ist)
146+ return (P Bound (sMN nm "spec") Erased)
147+ gen (App f a) = App <$> gen f <*> gen a
123-- | Checks if a given argument is a type class constraint argument
150-- | Checks if a given argument is a type class constraint argument
124classConstraint :: Idris.AbsSyntax.IState -> TT Name -> Bool
151classConstraint :: Idris.AbsSyntax.IState -> TT Name -> Bool
125classConstraint ist v
152classConstraint ist v
@@ -265,9 +292,9 @@ getSpecApps ist env tm = ga env (explicitNames tm) where
265 ga env tm@(App f a) | (P _ n _, args) <- unApply tm,
292 ga env tm@(App f a) | (P _ n _, args) <- unApply tm,
266 n `notElem` map fst (idris_metavars ist) =
293 n `notElem` map fst (idris_metavars ist) =
267 ga env f ++ ga env a ++
294 ga env f ++ ga env a ++
268− case (lookupCtxt n (idris_statics ist),
295+ case (lookupCtxtExact n (idris_statics ist),
269− lookupCtxt n (idris_implicits ist)) of
296+ lookupCtxtExact n (idris_implicits ist)) of
270− ([statics], [imps]) ->
297+ (Just statics, Just imps) ->
271 if (length statics == length args && or statics) then
298 if (length statics == length args && or statics) then
272 case buildApp env statics imps args [0..] of
299 case buildApp env statics imps args [0..] of
273 args -> [(n, args)]
300 args -> [(n, args)]