@@ -163,38 +163,55 @@ checkPositive n (cn, ty)
163 posArg t = True
163 posArg t = True
165calcProd :: IState -> FC -> Name -> [([Name], Term, Term)] -> Idris Totality
165calcProd :: IState -> FC -> Name -> [([Name], Term, Term)] -> Idris Totality
166−calcProd i fc n pats = do patsprod <- mapM prodRec pats
166+calcProd i fc topn pats
167− if (and patsprod)
167+ = cp topn pats []
168− then return Productive
169− else return (Partial NotProductive)
171 -- every application of n must be in an argument of a coinductive
169 -- every application of n must be in an argument of a coinductive
172 -- constructor, in every function reachable from here in the
170 -- constructor, in every function reachable from here in the
173 -- call graph.
171 -- call graph.
174−
172+ cp n pats done = do patsprod <- mapM (prodRec n done) pats
174+ then return Productive
175+ else return (Partial NotProductive)
175− prodRec :: ([Name], Term, Term) -> Idris Bool
177+ prodRec :: Name -> [Name] -> ([Name], Term, Term) -> Idris Bool
178+ prodRec n done _ | n `elem` done = return True
176− prodRec (_, _, tm) = prod False tm
179+ prodRec n done (_, _, tm) = prod n done False tm
181+ prod :: Name -> [Name] -> Bool -> Term -> Idris Bool
178− prod ok ap@(App _ _)
182+ prod n done ok ap@(App _ _)
179− | (P _ (UN "lazy") _, [_, arg]) <- unApply ap = prod ok arg
183+ | (P _ (UN "lazy") _, [_, arg]) <- unApply ap = prod n done ok arg
180− | (P nt f ty, args) <- unApply ap
184+ | (P nt f _, args) <- unApply ap
185+ = do recOK <- checkProdRec (n:done) f
186+ let ctxt = tt_ctxt i
187+ let [ty] = lookupTy f ctxt -- must exist!
181− = let co = cotype nt ty in
188+ let co = cotype nt f ty in
189+ if (not recOK) then return False else
182− if f == n
190+ if f == topn
183− then do argsprod <- mapM (prod co) args
191+ then do argsprod <- mapM (prod n done co) args
184− return (and (ok : argsprod) )
192+ return (and (ok : argsprod) )
185− else do argsprod <- mapM (prod co) args
193+ else do argsprod <- mapM (prod n done co) args
186− return (and argsprod)
194+ return (and argsprod)
187− prod ok (App f a) = liftM2 (&&) (prod False f) (prod False a)
195+ prod n done ok (App f a) = liftM2 (&&) (prod n done False f)
196+ (prod n done False a)
197+ prod n done ok (Bind _ (Let t v) sc)
188− prod ok (Bind _ (Let t v) sc) = liftM2 (&&) (prod False v) (prod False v)
198+ = liftM2 (&&) (prod n done False v) (prod n done False v)
189− prod ok (Bind _ b sc) = prod ok sc
199+ prod n done ok (Bind _ b sc) = prod n done ok sc
190− prod ok t = return True
200+ prod n done ok t = return True
202+ checkProdRec :: [Name] -> Name -> Idris Bool
204+ = case lookupCtxt f (idris_patdefs i) of
205+ [(def, _)] -> do ok <- mapM (prodRec f done) def
207+ _ -> return True -- defined elsewhere, can't call topn
192− cotype (DCon _ _) ty
209+ cotype (DCon _ _) n ty
193 | (P _ t _, _) <- unApply (getRetTy ty)
210 | (P _ t _, _) <- unApply (getRetTy ty)
194 = case lookupCtxt t (idris_datatypes i) of
211 = case lookupCtxt t (idris_datatypes i) of
195 [TI _ True _] -> True
212 [TI _ True _] -> True
196 _ -> False
213 _ -> False
197− cotype _ _ = False
214+ cotype nt n ty = False
199calcTotality :: [Name] -> FC -> Name -> [([Name], Term, Term)]
216calcTotality :: [Name] -> FC -> Name -> [([Name], Term, Term)]
200 -> Idris Totality
217 -> Idris Totality