@@ -13,6 +13,7 @@ import Control.Monad.State
13
13
import Libraries.Data.NameMap
14
14
import Libraries.Data.SortedMap
15
15
import Data.List
16
+ import Data.String
16
17
17
18
%default covering
18
19
@@ -610,28 +611,43 @@ nameIn defs tyns _ = pure False
610
611
611
612
-- Check an argument type doesn't contain a negative occurrence of any of
612
613
-- the given type names
613
- posArg : {auto c : Ref Ctxt Defs} ->
614
- Defs -> List Name -> NF [] -> Core Terminating
614
+ posArg : {auto c : Ref Ctxt Defs} ->
615
+ Defs -> List Name -> NF [] -> Core Terminating
616
+
617
+ posArgs : {auto c : Ref Ctxt Defs} ->
618
+ Defs -> List Name -> List (Closure []) -> Core Terminating
619
+ posArgs defs tyn [] = pure IsTerminating
620
+ posArgs defs tyn (x :: xs)
621
+ = do xNF <- evalClosure defs x
622
+ logNF " totality.positivity" 50 " Checking parameter for positivity" [] xNF
623
+ IsTerminating <- posArg defs tyn xNF
624
+ | err => pure err
625
+ posArgs defs tyn xs
626
+
615
627
-- a tyn can only appear in the parameter positions of
616
628
-- tc; report positivity failure if it appears anywhere else
617
- posArg defs tyns nf@(NTCon _ tc _ _ args) =
629
+ posArg defs tyns nf@(NTCon loc tc _ _ args) =
618
630
do logNF " totality.positivity" 50 " Found a type constructor" [] nf
619
- let testargs : List (Closure [])
620
- = case ! (lookupDefExact tc (gamma defs)) of
621
- Just (TCon _ _ params _ _ _ _ _ ) =>
622
- dropParams 0 params (map snd args)
623
- _ => map snd args
624
- if ! (anyM (nameIn defs tyns)
625
- ! (traverse (evalClosure defs) testargs))
626
- then pure (NotTerminating NotStrictlyPositive )
627
- else pure IsTerminating
631
+ testargs <- case ! (lookupDefExact tc (gamma defs)) of
632
+ Just (TCon _ _ params _ _ _ _ _ ) => do
633
+ log " totality.positivity" 50 $
634
+ unwords [show tc, " has" , show (length params), " parameters" ]
635
+ pure $ splitParams 0 params (map snd args)
636
+ _ => throw (GenericMsg loc (show tc ++ " not a data type" ))
637
+ let (params, indices) = testargs
638
+ False <- anyM (nameIn defs tyns) ! (traverse (evalClosure defs) indices)
639
+ | True => pure (NotTerminating NotStrictlyPositive )
640
+ posArgs defs tyns params
628
641
where
629
- dropParams : Nat -> List Nat -> List (Closure []) -> List (Closure [])
630
- dropParams i ps [] = []
631
- dropParams i ps (x :: xs)
642
+ splitParams : Nat -> List Nat -> List (Closure []) ->
643
+ ( List (Closure []) -- parameters (to be checked for strict positivity)
644
+ , List (Closure []) -- indices (to be checked for no mention at all)
645
+ )
646
+ splitParams i ps [] = ([], [])
647
+ splitParams i ps (x :: xs)
632
648
= if i `elem` ps
633
- then dropParams ( S i) ps xs
634
- else x :: dropParams (S i) ps xs
649
+ then mapFst (x :: ) (splitParams ( S i) ps xs)
650
+ else mapSnd ( x :: ) (splitParams (S i) ps xs)
635
651
-- a tyn can not appear as part of ty
636
652
posArg defs tyns nf@(NBind fc x (Pi _ _ e ty) sc)
637
653
= do logNF " totality.positivity" 50 " Found a Pi-type" [] nf
0 commit comments