on master help sign in
More efficiency improvements

More efforts to avoid allocation where no updates happen.

commit42c694ced49577c085da42d9b5966545cce1594a authorEdwin Brady <ecb10@st-andrews.ac.uk> dateWed 6 Aug 2014, 18:25 (12 years ago) parent02f7c64
7 files changed+91−28
CHANGELOG+11−4 libs/prelude/Prelude/Fin.idr+2−1 src/Idris/Core/Elaborate.hs+12−4 src/Idris/Core/ProofTerm.hs+33−16 src/Idris/Core/TT.hs+31−1 src/Idris/ElabTerm.hs+1−1 test/proof002/expected+1−1
CHANGELOG+11−4
@@ -1,9 +1,16 @@
11New in 0.9.15:
22--------------
3−* Two new tactics: skip and fail. Skip does nothing, and fail takes a string as an argument and produces it as an error.
4−* Corresponding reflected tactics Skip and Fail. Reflected Fail takes a list of ErrorReportParts as an argument, like error handlers produce, allowing access to the pretty-printer.
5−* Stop showing irrelevant and inaccessible internal names in the interactive prover
6−* The proof arguments in the List library functions are now implicit and solved automatically
3+* Two new tactics: skip and fail. Skip does nothing, and fail takes a string
4+ as an argument and produces it as an error.
5+* Corresponding reflected tactics Skip and Fail. Reflected Fail takes a list
6+ of ErrorReportParts as an argument, like error handlers produce, allowing
7+ access to the pretty-printer.
8+* Stop showing irrelevant and inaccessible internal names in the interactive
9+ prover.
10+* The proof arguments in the List library functions are now implicit and
11+ solved automatically.
12+* More efficient representation of proof state, leading to faster elaboration
13+ of large expressions.
714
815New in 0.9.14:
916--------------
libs/prelude/Prelude/Fin.idr+2−1
@@ -133,11 +133,12 @@ natToFin (S k) (S j) with (natToFin k j)
133133natToFin _ _ = Nothing
134134
135135integerToFin : Integer -> (n : Nat) -> Maybe (Fin n)
136+integerToFin x Z = Nothing -- make sure 'n' is concrete, to save reduction!
136137integerToFin x n = if x >= 0 then natToFin (cast x) n else Nothing
137138
138139||| Proof that some `Maybe` is actually `Just`
139140data IsJust : Maybe a -> Type where
140− ItIsJust : IsJust {a} (Just x)
141+ ItIsJust : IsJust (Just x)
141142
142143||| Allow overloading of Integer literals for Fin.
143144||| @ x the Integer that the user typed
src/Idris/Core/Elaborate.hs+12−4
@@ -498,10 +498,9 @@ apply' fillt fn imps =
498498 -- (remove from unified list before calling end_unify)
499499 hs <- get_holes
500500 ES (p, a) s prev <- get
501− let dont = head hs : dontunify p ++
502− if null imps then [] -- do all we can
503− else
504− map fst (filter (not . snd) (zip (map snd args) (map fst imps)))
501+ let dont = if null imps
502+ then head hs : dontunify p
503+ else getNonUnify (head hs : dontunify p) imps args
505504 let (n, hunis) = -- trace ("AVOID UNIFY: " ++ show (fn, dont) ++ "\n" ++ show ptm) $
506505 unified p
507506 let unify = -- trace ("Not done " ++ show hs) $
@@ -520,6 +519,15 @@ apply' fillt fn imps =
520519 Just (P _ t _) -> t
521520 _ -> n
522521
522+ getNonUnify acc [] _ = acc
523+ getNonUnify acc _ [] = acc
524+ getNonUnify acc ((i,_):is) ((a, t):as)
525+ | i = getNonUnify acc is as
526+ | otherwise = getNonUnify (t : acc) is as
527+
528+-- getNonUnify imps args = map fst (filter (not . snd) (zip (map snd args) (map fst imps)))
529+
530+
523531apply2 :: Raw -> [Maybe (Elab' aux ())] -> Elab' aux ()
524532apply2 fn elabs =
525533 do args <- prepare_apply fn (map isJust elabs)
src/Idris/Core/ProofTerm.hs+33−16
@@ -125,25 +125,42 @@ updateSolvedTerm :: [(Name, Term)] -> Term -> Term
125125updateSolvedTerm [] x = x
126126updateSolvedTerm xs x = -- updateSolved' xs x where
127127-- This version below saves allocations, because it doesn't need to reallocate
128−-- the term if there are no updates to do, but costs an extra pass. Below
129−-- version works better on larger terms...
130− if noneOf (map fst xs) x
131− then x
132− else updateSolved' xs x where
133− updateSolved' [] x = x
128+-- the term if there are no updates to do.
129+-- The Bool is ugly, and probably 'Maybe' would be less ugly, but >>= is
130+-- the wrong combinator. Feel free to tidy up as long as it's still as cheap :).
131+ fst $ updateSolved' xs x where
132+ updateSolved' [] x = (x, False)
134133 updateSolved' xs (Bind n (Hole ty) t)
135134 | Just v <- lookup n xs
136135 = case xs of
137− [_] -> substV v $ psubst n v t -- some may be Vs! Can't assume
138− -- explicit names
139− _ -> substV v $ psubst n v (updateSolved' xs t)
140− updateSolved' xs (Bind n b t)
141− | otherwise = Bind n (fmap (updateSolved' xs) b) (updateSolved' xs t)
142− updateSolved' xs (App f a)
143− = App (updateSolved' xs f) (updateSolved' xs a)
144− updateSolved' xs (P _ n@(MN _ _) _)
145− | Just v <- lookup n xs = v
146− updateSolved' xs t = t
136+ [_] -> (substV v $ psubst n v t, True) -- some may be Vs! Can't assume
137+ -- explicit names
138+ _ -> let (t', _) = updateSolved' xs t in
139+ (substV v $ psubst n v t', True)
140+ updateSolved' xs tm@(Bind n b t)
141+ | otherwise = let (t', ut) = updateSolved' xs t
142+ (b', ub) = updateSolvedB' xs b in
143+ if ut || ub then (Bind n b' t', True)
144+ else (tm, False)
145+ updateSolved' xs t@(App f a)
146+ = let (f', uf) = updateSolved' xs f
147+ (a', ua) = updateSolved' xs a in
148+ if uf || ua then (App f' a', True)
149+ else (t, False)
150+ updateSolved' xs t@(P _ n@(MN _ _) _)
151+ | Just v <- lookup n xs = (v, True)
152+ updateSolved' xs t = (t, False)
153+
154+ updateSolvedB' xs b@(Let t v) = let (t', ut) = updateSolved' xs t
155+ (v', uv) = updateSolved' xs v in
156+ if ut || uv then (Let t' v', True)
157+ else (b, False)
158+ updateSolvedB' xs b@(Guess t v) = let (t', ut) = updateSolved' xs t
159+ (v', uv) = updateSolved' xs v in
160+ if ut || uv then (Guess t' v', True)
161+ else (b, False)
162+ updateSolvedB' xs b = let (ty', u) = updateSolved' xs (binderTy b) in
163+ if u then (b { binderTy = ty' }, u) else (b, False)
147164
148165 noneOf ns (P _ n _) | n `elem` ns = False
149166 noneOf ns (App f a) = noneOf ns a && noneOf ns f
src/Idris/Core/TT.hs+31−1
@@ -935,7 +935,37 @@ subst :: Eq n => n {-^ The id to replace -} ->
935935 TT n {-^ The replacement term -} ->
936936 TT n {-^ The term to replace in -} ->
937937 TT n
938−subst n v tm = instantiate v (pToV n tm)
938+-- subst n v tm = instantiate v (pToV n tm)
939+subst n v tm = fst $ subst' 0 tm
940+ where
941+ -- keep track of updates to save allocations - this is a big win on
942+ -- large terms in particular
943+ -- ('Maybe' would be neater here, but >>= is not the right combinator.
944+ -- Feel free to tidy up, as long as it still saves allocating when no
945+ -- substitution happens...)
946+ subst' i (V x) | i == x = (v, True)
947+ subst' i (P _ x _) | n == x = (v, True)
948+ subst' i t@(Bind x b sc) | x /= n
949+ = let (b', ub) = substB' i b
950+ (sc', usc) = subst' (i+1) sc in
951+ if ub || usc then (Bind x b' sc', True) else (t, False)
952+ subst' i t@(App f a) = let (f', uf) = subst' i f
953+ (a', ua) = subst' i a in
954+ if uf || ua then (App f' a', True) else (t, False)
955+ subst' i t@(Proj x idx) = let (x', u) = subst' i x in
956+ if u then (Proj x' idx, u) else (t, False)
957+ subst' i t = (t, False)
958+
959+ substB' i b@(Let t v) = let (t', ut) = subst' i t
960+ (v', uv) = subst' i v in
961+ if ut || uv then (Let t' v', True)
962+ else (b, False)
963+ substB' i b@(Guess t v) = let (t', ut) = subst' i t
964+ (v', uv) = subst' i v in
965+ if ut || uv then (Guess t' v', True)
966+ else (b, False)
967+ substB' i b = let (ty', u) = subst' i (binderTy b) in
968+ if u then (b { binderTy = ty' }, u) else (b, False)
939969
940970-- If there are no Vs in the term (i.e. in proof state)
941971psubst :: Eq n => n -> TT n -> TT n -> TT n
src/Idris/ElabTerm.hs+1−1
@@ -244,7 +244,7 @@ elab ist info emode opts fn tm
244244 elab' ina (PConstant c) = do apply (RConstant c) []; solve
245245 elab' ina (PQuote r) = do fill r; solve
246246 elab' ina (PTrue fc _) = try (elab' ina (PRef fc unitCon))
247− (elab' ina (PRef fc unitTy))
247+ (elab' ina (PRef fc unitTy))
248248 elab' ina (PFalse fc) = elab' ina (PRef fc falseTy)
249249 elab' ina (PResolveTC (FC "HACK" _ _)) -- for chasing parent classes
250250 = do g <- goal; resolveTC False 5 g fn ist
test/proof002/expected+1−1
@@ -1,7 +1,7 @@
11Reflect.idr:207:38:When elaborating right hand side of testReflect1:
22When elaborating an application of function Reflect.getJust:
33 Can't unify
4− IsJust (Just x2)
4+ IsJust (Just x1)
55 with
66 IsJust (prove (getProof x))
77