0 | module Core.Termination
2 | import Core.Context.Log
4 | import Core.Normalise
7 | import Core.Termination.CallGraph
8 | import Core.Termination.Positivity
9 | import Core.Termination.SizeChange
11 | import Libraries.Data.NameMap
20 | checkIfGuarded : {auto c : Ref Ctxt Defs} ->
21 | FC -> Name -> Core ()
23 | = do logC "totality.termination.guarded" 6 $
do pure $
"Check if Guarded: " ++ show !(toFullNames n)
25 | Just (PMDef _ _ _ _ pats) <- lookupDefExact n (gamma defs)
27 | t <- allGuarded pats
28 | when t $
setFlag fc n AllGuarded
30 | guardedNF : Defs -> Env Term vars -> NF vars -> Core Bool
31 | guardedNF defs env (NDCon _ _ _ _ args) = pure True
32 | guardedNF defs env (NApp _ (NRef _ n) args)
33 | = do Just gdef <- lookupCtxtExact n (gamma defs)
34 | | Nothing => pure False
35 | pure (AllGuarded `elem` flags gdef)
36 | guardedNF defs env _ = pure False
38 | checkNotFn : Defs -> Name -> Core Bool
40 | = do Just gdef <- lookupCtxtExact n (gamma defs)
41 | | Nothing => pure False
42 | case definition gdef of
43 | DCon {} => pure True
44 | _ => pure (multiplicity gdef == erased
45 | || (AllGuarded `elem` flags gdef))
47 | guarded : {vars : _} -> Env Term vars -> Term vars -> Core Bool
49 | = do defs <- get Ctxt
50 | empty <- clearDefs defs
51 | tmnf <- nf empty env tm
52 | if !(guardedNF defs env tmnf)
53 | then do Just gdef <- lookupCtxtExact n (gamma defs)
54 | | Nothing => pure False
55 | allM (checkNotFn defs) (keys (refersTo gdef))
58 | allGuarded : List (
vs ** (Env Term vs, Term vs, Term vs))
-> Core Bool
59 | allGuarded [] = pure True
60 | allGuarded ((
_ ** (env, lhs, rhs))
:: ps)
61 | = if !(guarded env rhs)
67 | checkTerminating : {auto c : Ref Ctxt Defs} ->
68 | FC -> Name -> Core Terminating
69 | checkTerminating loc n
70 | = do tot <- getTotality loc n
71 | logC "totality.termination" 6 $
do pure $
"Checking termination: " ++ show !(toFullNames n)
72 | case isTerminating tot of
74 | do tot' <- calcTerminating loc n
75 | setTerminating loc n tot'
82 | checkPositive : {auto c : Ref Ctxt Defs} ->
83 | FC -> Name -> Core Terminating
84 | checkPositive loc n_in
85 | = do n <- toResolvedNames n_in
86 | tot <- getTotality loc n
87 | logC "totality.positivity" 6 $
do pure $
"Checking positivity: " ++ show !(toFullNames n)
88 | case isTerminating tot of
90 | do (tot', cons) <- calcPositive loc n
91 | setTerminating loc n tot'
92 | traverse_ (\c => setTerminating loc c tot') cons
100 | checkTotal : {auto c : Ref Ctxt Defs} ->
101 | FC -> Name -> Core Terminating
102 | checkTotal loc n_in
103 | = do defs <- get Ctxt
104 | let Just nidx = getNameID n_in (gamma defs)
105 | | Nothing => undefinedName loc n_in
106 | let n = Resolved nidx
107 | tot <- getTotality loc n
108 | logC "totality" 5 $
do pure $
"Checking totality: " ++ show !(toFullNames n)
110 | case isTerminating tot of
112 | mgdef <- lookupCtxtExact n (gamma defs)
113 | case definition <$> mgdef of
115 | => checkPositive loc n
116 | _ => do whenJust (refersToM =<< mgdef) $
\ refs =>
117 | log "totality" 5 $
" Mutually defined with:"
118 | ++ show !(traverse toFullNames (keys refs))
119 | checkTerminating loc n