@@ -198,9 +198,10 @@ calcTotality path fc n pats
198 = do orders <- mapM ctot pats
198 = do orders <- mapM ctot pats
199 let order = sortBy cmpOrd $ concat orders
199 let order = sortBy cmpOrd $ concat orders
200 let (errs, valid) = partitionEithers order
200 let (errs, valid) = partitionEithers order
201− let lex = stripXX valid
201+ let lex = stripNoLT (stripXX valid)
202 case errs of
202 case errs of
203− [] -> do logLvl 3 $ show n ++ ":\n" ++ showSep "\n" (map show lex)
203+ [] -> do logLvl 3 $ show n ++ ":\n" ++ showSep "\n" (map show lex)
204+ logLvl 10 $ show pats
204 checkDecreasing lex
205 checkDecreasing lex
205 (e : _) -> return e -- FIXME: should probably combine them
206 (e : _) -> return e -- FIXME: should probably combine them
@@ -216,13 +217,16 @@ calcTotality path fc n pats
216 dec [] = False
217 dec [] = False
217 dec (LexLT : _) = True
218 dec (LexLT : _) = True
218 dec (LexEQ : xs) = dec xs
219 dec (LexEQ : xs) = dec xs
219− dec (LexXX : _) = False
220+ dec (LexXX : xs) = False
221 stripXX [] = []
222 stripXX [] = []
222 stripXX v@(c : cs)
223 stripXX v@(c : cs)
223 = case span (==LexXX) c of
224 = case span (==LexXX) c of
224 (ns, rest) -> map (drop (length ns)) v
225 (ns, rest) -> map (drop (length ns)) v
227+ -- argument positions which are never LT are no use to us
228+ stripNoLT xs = transpose (filter (any (==LexLT)) (transpose xs))
226 ctot (lhs, rhs)
230 ctot (lhs, rhs)
227 | (_, args) <- unApply lhs
231 | (_, args) <- unApply lhs
228 = do -- check lhs doesn't use any dodgy names
232 = do -- check lhs doesn't use any dodgy names
@@ -232,7 +236,7 @@ calcTotality path fc n pats
232 chkOrd ords args (Bind n (Let t v) sc)
236 chkOrd ords args (Bind n (Let t v) sc)
233 = do ov <- chkOrd ords args v
237 = do ov <- chkOrd ords args v
234 chkOrd ov args sc
238 chkOrd ov args sc
235− chkOrd ords args (Bind n b sc) = chkOrd ords args sc
239+ chkOrd ords args (Bind n b sc) = chkOrd ords (args ++ [P Ref n Erased]) sc
236 chkOrd ords args ap@(App f a)
240 chkOrd ords args ap@(App f a)
237 | (P _ fn _, args') <- unApply ap
241 | (P _ fn _, args') <- unApply ap
238 = if fn == n && length args == length args'
242 = if fn == n && length args == length args'
@@ -269,17 +273,29 @@ checkTotality path fc n
269 case t of
273 case t of
270 Unchecked -> case lookupDef Nothing n ctxt of
274 Unchecked -> case lookupDef Nothing n ctxt of
271 [CaseOp _ _ pats _ _ _ _] ->
275 [CaseOp _ _ pats _ _ _ _] ->
277+ let opts = case lookupCtxt Nothing n (idris_flags i) of
280+ t' <- if AssertTotal `elem` opts
281+ then return $ Total []
272− do t' <- calcTotality path fc n pats
282+ else calcTotality path fc n pats
274− case lookupCtxt Nothing n (idris_flags i) of
275− [fs] -> if TotalFn `elem` fs then
283+ if TotalFn `elem` opts
276− case t' of
284+ then case t' of
277− Total _ -> return ()
285+ Total _ -> return ()
278− e -> totalityError t'
286+ e -> totalityError t'
280− _ -> return ()
287+ else return ()
281 setTotality n t'
288 setTotality n t'
282 addIBC (IBCTotal n t')
289 addIBC (IBCTotal n t')
290+ -- if it's not total, it can't reduce, to keep
291+ -- typechecking decidable
293+-- FIXME: Put this back when we can handle mutually recursive things
295+-- do setAccessibility n Frozen
296+-- addIBC (IBCAccess n Frozen)
297+-- iputStrLn $ "HIDDEN: " ++ show n ++ show p
283 return t'
299 return t'
284 _ -> return $ Total []
300 _ -> return $ Total []
285 x -> return x
301 x -> return x