@@ -432,6 +432,56 @@ checkDeclTotality (fc, n)
432432-- sizechange1 ... sizechange2 is how their size has changed wrt the input to f
433433-- Nothing, if the argument is unrelated to the input
434434
435−buildSCG :: SC -> [Name] -> [(Name, [[Maybe (Name, SizeChange)]])]
436−buildSCG _ _ = []
435+buildSCG :: IState -> SC -> [Name] -> [(Name, [Maybe (Name, SizeChange)])]
436+buildSCG ist sc args = scg sc (zip args args) (zip args (zip args (repeat Same)))
437+ where
438+ scg :: SC -> [(Name, Name)] -> -- local var, originating top level var
439+ [(Name, (Name, SizeChange))] -> -- map from orig to new and relationship
440+ [(Name, [Maybe (Name, SizeChange)])]
441+ scg (Case x alts) vars szs = concatMap (scgAlt x vars szs) alts
442+ scg (STerm tm) vars szs = scgTerm tm vars szs
443+ scg _ _ _ = []
444+
445+ -- how the arguments relate - either Smaller or Unknown
446+ argRels :: Name -> [(Name, SizeChange)]
447+ argRels n = let ctxt = tt_ctxt ist
448+ [ty] = lookupTy Nothing n ctxt -- must exist!
449+ P _ nty _ = fst (unApply (getRetTy ty))
450+ args = map snd (getArgTys ty) in
451+ map (getRel nty) (map (fst . unApply) args)
452+ where
453+ getRel ty (P _ n' _) | n' == ty = (n, Smaller)
454+ getRel ty _ = (n, Unknown)
455+
456+ scgAlt x vars szs (ConCase n _ args sc)
457+ -- all args smaller than top variable of x in sc
458+ -- (as long as they are in the same type family)
459+ | Just tvar <- lookup x vars
460+ = let arel = argRels n
461+ szs' = zipWith (\arg (_,t) -> (arg, (x, t))) args arel ++ szs
462+ vars' = zip args (repeat tvar) ++ vars in
463+ scg sc vars' szs'
464+ | otherwise = scg sc vars szs
465+ scgAlt x vars szs (ConstCase _ sc) = scg sc vars szs
466+ scgAlt x vars szs (DefaultCase sc) = scg sc vars szs
467+
468+ scgTerm f@(App _ _) vars szs
469+ | (P _ fn _, args) <- unApply f
470+ = let rest = concatMap (\x -> scgTerm x vars szs) args in
471+ case lookup fn vars of
472+ Just _ -> rest
473+ Nothing -> (fn, map (mkChange szs) args) : rest
474+ scgTerm (App f a) vars szs
475+ = scgTerm f vars szs ++ scgTerm a vars szs
476+ scgTerm (Bind n (Let t v) e) vars szs
477+ = scgTerm v vars szs ++ scgTerm e vars szs
478+ scgTerm (Bind n _ e) vars szs
479+ = scgTerm e ((n, n) : vars) szs
480+ scgTerm _ _ _ = []
481+
482+ mkChange :: [(Name, (Name, SizeChange))] -> Term -> Maybe (Name, SizeChange)
483+ mkChange szs (P _ n ty) = case lookup n szs of
484+ Just (_, Unknown) -> Nothing
485+ t -> t
486+ mkChange _ _ = Nothing
437487