{-# LANGUAGE NondecreasingIndentation #-}
{-# LANGUAGE TypeApplications #-}

{-| Coverage checking, case splitting, and splitting for refine tactics.

 -}

module Agda.TypeChecking.Coverage
  ( SplitClause(..), clauseToSplitClause, insertTrailingArgs
  , Covering(..), splitClauses
  , coverageCheck
  , isCovered
  , splitClauseWithAbsurd
  , splitLast
  , splitResult
  , normaliseProjP
  ) where

import Prelude hiding (null, (!!))  -- do not use partial functions like !!

import Control.Monad
import Control.Monad.Except
import Control.Monad.Trans ( lift )

import Data.Foldable (for_)
import qualified Data.List as List
import Data.Map (Map)
import qualified Data.Map as Map
import qualified Data.Set as Set
import Data.IntSet (IntSet)
import qualified Data.IntSet as IntSet

import qualified Agda.Benchmarking as Bench

import Agda.Syntax.Common
import Agda.Syntax.Position
import Agda.Syntax.Internal hiding (DataOrRecord)
import Agda.Syntax.Internal.Pattern
import Agda.Syntax.Translation.InternalToAbstract (NamedClause(..))

import Agda.TypeChecking.Primitive hiding (Nat)
import Agda.TypeChecking.Monad
import qualified Agda.TypeChecking.Monad.Benchmark as Bench

import Agda.TypeChecking.Rules.LHS (DataOrRecord, checkSortOfSplitVar)
import Agda.TypeChecking.Rules.LHS.Problem (allFlexVars)
import Agda.TypeChecking.Rules.LHS.Unify
import Agda.TypeChecking.Rules.Term (unquoteTactic)

import Agda.TypeChecking.Coverage.Match
import Agda.TypeChecking.Coverage.SplitTree
import Agda.TypeChecking.Coverage.SplitClause
import Agda.TypeChecking.Coverage.Cubical


import Agda.TypeChecking.Conversion (tryConversion, equalType)
import Agda.TypeChecking.Datatypes (getConForm)
import {-# SOURCE #-} Agda.TypeChecking.Empty ( checkEmptyTel, isEmptyTel, isEmptyType )
import Agda.TypeChecking.Irrelevance
import Agda.TypeChecking.Pretty
import Agda.TypeChecking.Substitute
import Agda.TypeChecking.Reduce
import Agda.TypeChecking.Records
import Agda.TypeChecking.Telescope
import Agda.TypeChecking.MetaVars
import Agda.TypeChecking.Warnings

import Agda.Interaction.Options

import Agda.Utils.Either
import Agda.Utils.Function
import Agda.Utils.Functor
import Agda.Utils.List
import Agda.Utils.Maybe
import Agda.Utils.Monad
import Agda.Utils.Null
import Agda.Utils.Permutation
import Agda.Syntax.Common.Pretty (prettyShow)
import Agda.Utils.Singleton
import Agda.Utils.Size
import Agda.Utils.Tuple

import Agda.Utils.Impossible
import Data.IntMap (IntMap)
import qualified Data.IntMap as IntMap
import Control.Monad.State


type CoverM = ExceptT SplitError TCM

-- | Top-level function for checking pattern coverage.
--
--   Effects:
--
--   - Marks unreachable clauses as such in the signature.
--
--   - Adds missing instances clauses to the signature.
--
coverageCheck
  :: QName     -- ^ Name @f@ of definition.
  -> Type      -- ^ Absolute type (including the full parameter telescope).
  -> [Clause]  -- ^ Clauses of @f@.  These are the very clauses of @f@ in the signature.
  -> TCM SplitTree
coverageCheck :: QName -> Type -> [Clause] -> TCM SplitTree
coverageCheck QName
f Type
t [Clause]
cs = do
  [Char] -> Int -> [Char] -> TCMT IO ()
forall (m :: * -> *).
MonadDebug m =>
[Char] -> Int -> [Char] -> m ()
reportSLn [Char]
"tc.cover.top" Int
30 ([Char] -> TCMT IO ()) -> [Char] -> TCMT IO ()
forall a b. (a -> b) -> a -> b
$ [Char]
"entering coverageCheck for " [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ QName -> [Char]
forall a. Pretty a => a -> [Char]
prettyShow QName
f
  [Char] -> Int -> TCMT IO Doc -> TCMT IO ()
forall (m :: * -> *).
MonadDebug m =>
[Char] -> Int -> TCMT IO Doc -> m ()
reportSDoc [Char]
"tc.cover.top" Int
75 (TCMT IO Doc -> TCMT IO ()) -> TCMT IO Doc -> TCMT IO ()
forall a b. (a -> b) -> a -> b
$ TCMT IO Doc
"  of type (raw): " TCMT IO Doc -> TCMT IO Doc -> TCMT IO Doc
forall (m :: * -> *). Applicative m => m Doc -> m Doc -> m Doc
<+> ([Char] -> TCMT IO Doc
forall (m :: * -> *). Applicative m => [Char] -> m Doc
text ([Char] -> TCMT IO Doc) -> (Type -> [Char]) -> Type -> TCMT IO Doc
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Type -> [Char]
forall a. Pretty a => a -> [Char]
prettyShow) Type
t
  [Char] -> Int -> TCMT IO Doc -> TCMT IO ()
forall (m :: * -> *).
MonadDebug m =>
[Char] -> Int -> TCMT IO Doc -> m ()
reportSDoc [Char]
"tc.cover.top" Int
45 (TCMT IO Doc -> TCMT IO ()) -> TCMT IO Doc -> TCMT IO ()
forall a b. (a -> b) -> a -> b
$ TCMT IO Doc
"  of type: " TCMT IO Doc -> TCMT IO Doc -> TCMT IO Doc
forall (m :: * -> *). Applicative m => m Doc -> m Doc -> m Doc
<+> Type -> TCMT IO Doc
forall a (m :: * -> *). (PrettyTCM a, MonadPretty m) => a -> m Doc
forall (m :: * -> *). MonadPretty m => Type -> m Doc
prettyTCM Type
t
  TelV gamma a <- Int -> Type -> TCMT IO (TelV Type)
forall (m :: * -> *).
(MonadReduce m, MonadAddContext m) =>
Int -> Type -> m (TelV Type)
telViewUpTo (-Int
1) Type
t
  reportSLn "tc.cover.top" 30 $ "coverageCheck: computed telView"

  let -- n             = arity
      -- xs            = variable patterns fitting lgamma
      n            = Telescope -> Int
forall a. Sized a => a -> Int
size Telescope
gamma
      xs           =  (NamedArg SplitPattern -> NamedArg SplitPattern)
-> [NamedArg SplitPattern] -> [NamedArg SplitPattern]
forall a b. (a -> b) -> [a] -> [b]
map (Origin -> NamedArg SplitPattern -> NamedArg SplitPattern
forall a. LensOrigin a => Origin -> a -> a
setOrigin Origin
Inserted) ([NamedArg SplitPattern] -> [NamedArg SplitPattern])
-> [NamedArg SplitPattern] -> [NamedArg SplitPattern]
forall a b. (a -> b) -> a -> b
$ Telescope -> [NamedArg SplitPattern]
forall a t. DeBruijn a => Tele (Dom t) -> [NamedArg a]
teleNamedArgs Telescope
gamma

  reportSLn "tc.cover.top" 30 $ "coverageCheck: getDefFreeVars"

      -- The initial module parameter substitutions need to be weakened by the
      -- number of arguments that aren't module parameters.
  fv           <- getDefFreeVars f

  reportSLn "tc.cover.top" 30 $ "coverageCheck: getting checkpoints"

  -- TODO: does this make sense? Why are we weakening by n - fv?
  checkpoints <- applySubst (raiseS (n - fv)) <$> viewTC eCheckpoints

      -- construct the initial split clause
  let sc = Telescope
-> [NamedArg SplitPattern]
-> Substitution' SplitPattern
-> Map CheckpointId (Substitution' Term)
-> Maybe (Dom Type)
-> SplitClause
SClause Telescope
gamma [NamedArg SplitPattern]
xs Substitution' SplitPattern
forall a. Substitution' a
idS Map CheckpointId (Substitution' Term)
checkpoints (Maybe (Dom Type) -> SplitClause)
-> Maybe (Dom Type) -> SplitClause
forall a b. (a -> b) -> a -> b
$ Dom Type -> Maybe (Dom Type)
forall a. a -> Maybe a
Just (Dom Type -> Maybe (Dom Type)) -> Dom Type -> Maybe (Dom Type)
forall a b. (a -> b) -> a -> b
$ Type -> Dom Type
forall a. a -> Dom a
defaultDom Type
a

  reportSDoc "tc.cover.top" 10 $ do
    let prCl Clause
cl = Telescope -> m Doc -> m Doc
forall b (m :: * -> *) a.
(AddContext b, MonadAddContext m) =>
b -> m a -> m a
forall (m :: * -> *) a.
MonadAddContext m =>
Telescope -> m a -> m a
addContext (Clause -> Telescope
clauseTel Clause
cl) (m Doc -> m Doc) -> m Doc -> m Doc
forall a b. (a -> b) -> a -> b
$
                  NAPs -> m Doc
forall (m :: * -> *). MonadPretty m => NAPs -> m Doc
prettyTCMPatternList (NAPs -> m Doc) -> NAPs -> m Doc
forall a b. (a -> b) -> a -> b
$ Clause -> NAPs
namedClausePats Clause
cl
    vcat
      [ text $ "Coverage checking " ++ prettyShow f ++ " with patterns:"
      , nest 2 $ vcat $ map prCl cs
      ]

  -- used = actually used clauses for cover
  -- pss  = non-covered cases
  CoverResult splitTree used pss qss noex <- cover f cs sc

  -- Andreas, 2018-11-12, issue #378:
  -- some indices in @used@ and @noex@ point outside of @cs@,
  -- since missing hcomp clauses have been added during the course of @cover@.
  -- We simply delete theses indices from @noex@.
  noex <- return $ List.filter (< length cs) $ IntSet.toList noex

  reportSDoc "tc.cover.top" 10 $ vcat
    [ "cover computed!"
    , text $ "used clauses: " ++ show used
    , text $ "non-exact clauses: " ++ show noex
    ]
  reportSDoc "tc.cover.splittree" 10 $ vcat
    [ "generated split tree for" <+> prettyTCM f
    , text $ prettyShow splitTree
    ]
  reportSDoc "tc.cover.covering" 10 $ vcat
    [ text $ "covering patterns for " ++ prettyShow f
    , nest 2 $ vcat $ map (\ Clause
cl -> Telescope -> TCMT IO Doc -> TCMT IO Doc
forall b (m :: * -> *) a.
(AddContext b, MonadAddContext m) =>
b -> m a -> m a
forall (m :: * -> *) a.
MonadAddContext m =>
Telescope -> m a -> m a
addContext (Clause -> Telescope
clauseTel Clause
cl) (TCMT IO Doc -> TCMT IO Doc) -> TCMT IO Doc -> TCMT IO Doc
forall a b. (a -> b) -> a -> b
$ NAPs -> TCMT IO Doc
forall (m :: * -> *). MonadPretty m => NAPs -> m Doc
prettyTCMPatternList (NAPs -> TCMT IO Doc) -> NAPs -> TCMT IO Doc
forall a b. (a -> b) -> a -> b
$ Clause -> NAPs
namedClausePats Clause
cl) qss
    ]

  -- Storing the covering clauses so that checkIApplyConfluence_ can
  -- find them later.
  -- Andreas, 2019-03-27, only needed when --cubical
  -- Jesper, 2022-10-18, also needed for some backends, so keep when flag says so
  opts <- pragmaOptions
  when (isJust (optCubical opts) || optKeepCoveringClauses opts) $
    modifySignature $ updateDefinition f $ updateTheDef $ updateCovering $ const qss


  -- filter out the missing clauses that are absurd.
  pss <- ifNotM (optInferAbsurdClauses <$> pragmaOptions) (pure pss) {-else-} $
   flip filterM pss $ \(Telescope
tel,NAPs
ps) ->
    -- Andreas, 2019-04-13, issue #3692: when adding missing absurd
    -- clauses, also put the absurd pattern in.
    TCMT IO (Either ErrorNonEmpty Int)
-> (ErrorNonEmpty -> TCMT IO Bool)
-> (Int -> TCMT IO Bool)
-> TCMT IO Bool
forall (m :: * -> *) a b c.
Monad m =>
m (Either a b) -> (a -> m c) -> (b -> m c) -> m c
caseEitherM (Range -> Telescope -> TCMT IO (Either ErrorNonEmpty Int)
checkEmptyTel Range
forall a. Range' a
noRange Telescope
tel) (\ ErrorNonEmpty
_ -> Bool -> TCMT IO Bool
forall a. a -> TCMT IO a
forall (m :: * -> *) a. Monad m => a -> m a
return Bool
True) ((Int -> TCMT IO Bool) -> TCMT IO Bool)
-> (Int -> TCMT IO Bool) -> TCMT IO Bool
forall a b. (a -> b) -> a -> b
$ \ Int
l -> do
      -- Now, @l@ is the first type in @tel@ (counting from 0=leftmost)
      -- which is empty.  Turn it into a de Bruijn index @i@.
      let i :: Int
i = Telescope -> Int
forall a. Sized a => a -> Int
size Telescope
tel Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1 Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
l
      -- Build a substitution mapping this pattern variable to the absurd pattern.
      let sub :: PatternSubstitution
sub = Int -> DeBruijnPattern -> PatternSubstitution
forall a. EndoSubst a => Int -> a -> Substitution' a
inplaceS Int
i (DeBruijnPattern -> PatternSubstitution)
-> DeBruijnPattern -> PatternSubstitution
forall a b. (a -> b) -> a -> b
$ Int -> DeBruijnPattern
absurdP Int
i
        -- ifNotM (isEmptyTel tel) (return True) $ do
      -- Jesper, 2018-11-28, Issue #3407: if the clause is absurd,
      -- add the appropriate absurd clause to the definition.
      let cl :: Clause
cl = Clause { clauseLHSRange :: Range
clauseLHSRange  = Range
forall a. Range' a
noRange
                      , clauseFullRange :: Range
clauseFullRange = Range
forall a. Range' a
noRange
                      , clauseTel :: Telescope
clauseTel       = Telescope
tel
                      , namedClausePats :: NAPs
namedClausePats = Substitution' (SubstArg NAPs) -> NAPs -> NAPs
forall a. Subst a => Substitution' (SubstArg a) -> a -> a
applySubst PatternSubstitution
Substitution' (SubstArg NAPs)
sub NAPs
ps
                      , clauseBody :: Maybe Term
clauseBody      = Maybe Term
forall a. Maybe a
Nothing
                      , clauseType :: Maybe (Arg Type)
clauseType      = Maybe (Arg Type)
forall a. Maybe a
Nothing
                      , clauseCatchall :: Bool
clauseCatchall    = Bool
True       -- absurd clauses are safe as catch-all
                      , clauseExact :: Maybe Bool
clauseExact       = Bool -> Maybe Bool
forall a. a -> Maybe a
Just Bool
False
                      , clauseRecursive :: Maybe Bool
clauseRecursive   = Bool -> Maybe Bool
forall a. a -> Maybe a
Just Bool
False
                      , clauseUnreachable :: Maybe Bool
clauseUnreachable = Bool -> Maybe Bool
forall a. a -> Maybe a
Just Bool
False
                      , clauseEllipsis :: ExpandedEllipsis
clauseEllipsis    = ExpandedEllipsis
NoEllipsis
                      , clauseWhereModule :: Maybe ModuleName
clauseWhereModule = Maybe ModuleName
forall a. Maybe a
Nothing
                      }
      [Char] -> Int -> TCMT IO Doc -> TCMT IO ()
forall (m :: * -> *).
MonadDebug m =>
[Char] -> Int -> TCMT IO Doc -> m ()
reportSDoc [Char]
"tc.cover.missing" Int
20 (TCMT IO Doc -> TCMT IO ()) -> TCMT IO Doc -> TCMT IO ()
forall a b. (a -> b) -> a -> b
$ TCMT IO Doc -> TCMT IO Doc
forall (tcm :: * -> *) a.
(MonadTCEnv tcm, ReadTCState tcm) =>
tcm a -> tcm a
inTopContext (TCMT IO Doc -> TCMT IO Doc) -> TCMT IO Doc -> TCMT IO Doc
forall a b. (a -> b) -> a -> b
$ do
        [TCMT IO Doc] -> TCMT IO Doc
forall (m :: * -> *) (t :: * -> *).
(Applicative m, Foldable t) =>
t (m Doc) -> m Doc
sep [ TCMT IO Doc
"adding missing absurd clause"
            , Int -> TCMT IO Doc -> TCMT IO Doc
forall (m :: * -> *). Functor m => Int -> m Doc -> m Doc
nest Int
2 (TCMT IO Doc -> TCMT IO Doc) -> TCMT IO Doc -> TCMT IO Doc
forall a b. (a -> b) -> a -> b
$ QNamed Clause -> TCMT IO Doc
forall a (m :: * -> *). (PrettyTCM a, MonadPretty m) => a -> m Doc
forall (m :: * -> *). MonadPretty m => QNamed Clause -> m Doc
prettyTCM (QNamed Clause -> TCMT IO Doc) -> QNamed Clause -> TCMT IO Doc
forall a b. (a -> b) -> a -> b
$ QName -> Clause -> QNamed Clause
forall a. QName -> a -> QNamed a
QNamed QName
f Clause
cl
            ]
      [Char] -> Int -> TCMT IO Doc -> TCMT IO ()
forall (m :: * -> *).
MonadDebug m =>
[Char] -> Int -> TCMT IO Doc -> m ()
reportSDoc [Char]
"tc.cover.missing" Int
80 (TCMT IO Doc -> TCMT IO ()) -> TCMT IO Doc -> TCMT IO ()
forall a b. (a -> b) -> a -> b
$ TCMT IO Doc -> TCMT IO Doc
forall (tcm :: * -> *) a.
(MonadTCEnv tcm, ReadTCState tcm) =>
tcm a -> tcm a
inTopContext (TCMT IO Doc -> TCMT IO Doc) -> TCMT IO Doc -> TCMT IO Doc
forall a b. (a -> b) -> a -> b
$ [TCMT IO Doc] -> TCMT IO Doc
forall (m :: * -> *) (t :: * -> *).
(Applicative m, Foldable t) =>
t (m Doc) -> m Doc
vcat
        [ TCMT IO Doc
"l   = " TCMT IO Doc -> TCMT IO Doc -> TCMT IO Doc
forall (m :: * -> *). Applicative m => m Doc -> m Doc -> m Doc
<+> Int -> TCMT IO Doc
forall (m :: * -> *) a. (Applicative m, Pretty a) => a -> m Doc
pretty Int
l
        , TCMT IO Doc
"i   = " TCMT IO Doc -> TCMT IO Doc -> TCMT IO Doc
forall (m :: * -> *). Applicative m => m Doc -> m Doc -> m Doc
<+> Int -> TCMT IO Doc
forall (m :: * -> *) a. (Applicative m, Pretty a) => a -> m Doc
pretty Int
i
        , TCMT IO Doc
"cl  = " TCMT IO Doc -> TCMT IO Doc -> TCMT IO Doc
forall (m :: * -> *). Applicative m => m Doc -> m Doc -> m Doc
<+> QNamed Clause -> TCMT IO Doc
forall (m :: * -> *) a. (Applicative m, Pretty a) => a -> m Doc
pretty (QName -> Clause -> QNamed Clause
forall a. QName -> a -> QNamed a
QNamed QName
f Clause
cl)
        ]
      QName -> [Clause] -> TCMT IO ()
forall (m :: * -> *).
(MonadConstraint m, MonadTCState m) =>
QName -> [Clause] -> m ()
addClauses QName
f [Clause
cl]
      Bool -> TCMT IO Bool
forall a. a -> TCMT IO a
forall (m :: * -> *) a. Monad m => a -> m a
return Bool
False

  -- report a warning if there are uncovered cases,
  unless (null pss) $ do
    stLocalPartialDefs `modifyTCLens` Set.insert f
    whenM ((YesCoverageCheck ==) <$> viewTC eCoverageCheck) $
      setCurrentRange cs $ warning $ CoverageIssue f pss

  -- Andreas, 2017-08-28, issue #2723:
  -- Mark clauses as reachable or unreachable in the signature.
  -- Andreas, 2020-11-19, issue #5065
  -- Remember whether clauses are exact or not.
  let (is0, cs1) = unzip $ for (zip [0..] cs) $ \ (Int
i, Clause
cl) -> let
          unreachable :: Bool
unreachable = Int
i Int -> IntSet -> Bool
`IntSet.notMember` IntSet
used
          exact :: Bool
exact       = Int
i Int -> IntSet -> Bool
`IntSet.notMember` ([Int] -> IntSet
IntSet.fromList [Int]
noex)
        in (Bool -> Int -> Maybe Int
forall a. Bool -> a -> Maybe a
boolToMaybe Bool
unreachable Int
i, Clause
cl
             { clauseUnreachable = Just unreachable
             , clauseExact       = Just exact
             })
  -- is = indices of unreachable clauses
  let is = [Maybe Int] -> [Int]
forall a. [Maybe a] -> [a]
catMaybes [Maybe Int]
is0
  reportSDoc "tc.cover.top" 10 $ vcat
    [ text $ "unreachable clauses: " ++ if null is then "(none)" else show is
    ]
  -- Replace the first clauses by @cs1@.  There might be more
  -- added by @inferMissingClause@.
  modifyFunClauses f $ \ [Clause]
cs0 -> [Clause]
cs1 [Clause] -> [Clause] -> [Clause]
forall a. [a] -> [a] -> [a]
++ Int -> [Clause] -> [Clause]
forall a. Int -> [a] -> [a]
drop ([Clause] -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [Clause]
cs1) [Clause]
cs0

  -- Warn if there are unreachable clauses and mark them as unreachable.
  unless (null is) $ do
    -- Warn about unreachable clauses.
    let unreached = (Clause -> Bool) -> [Clause] -> [Clause]
forall a. (a -> Bool) -> [a] -> [a]
filter ((Bool -> Maybe Bool
forall a. a -> Maybe a
Just Bool
True Maybe Bool -> Maybe Bool -> Bool
forall a. Eq a => a -> a -> Bool
==) (Maybe Bool -> Bool) -> (Clause -> Maybe Bool) -> Clause -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Clause -> Maybe Bool
clauseUnreachable) [Clause]
cs1
    let ranges    = (Clause -> Range) -> [Clause] -> [Range]
forall a b. (a -> b) -> [a] -> [b]
map Clause -> Range
clauseFullRange [Clause]
unreached
    setCurrentRange ranges $ warning $ UnreachableClauses f ranges

  -- Report a warning if there are clauses that are not preserved as
  -- definitional equalities and --exact-split is enabled
  -- and they are not labelled as CATCHALL.
  let noexclauses = [Int] -> (Int -> Maybe Clause) -> [Clause]
forall a b. [a] -> (a -> Maybe b) -> [b]
forMaybe [Int]
noex ((Int -> Maybe Clause) -> [Clause])
-> (Int -> Maybe Clause) -> [Clause]
forall a b. (a -> b) -> a -> b
$ \ Int
i -> do
        let cl :: Clause
cl = Clause -> [Clause] -> Int -> Clause
forall a. a -> [a] -> Int -> a
indexWithDefault Clause
forall a. HasCallStack => a
__IMPOSSIBLE__ [Clause]
cs1 Int
i
        if Clause -> Bool
clauseCatchall Clause
cl then Maybe Clause
forall a. Maybe a
Nothing else Clause -> Maybe Clause
forall a. a -> Maybe a
Just Clause
cl
  unless (null noexclauses) $ do
      setCurrentRange (map clauseLHSRange noexclauses) $
        warning $ CoverageNoExactSplit f $ noexclauses
  return splitTree

-- | Top-level function for eliminating redundant clauses in the interactive
--   case splitter
isCovered :: QName -> [Clause] -> SplitClause -> TCM Bool
isCovered :: QName -> [Clause] -> SplitClause -> TCMT IO Bool
isCovered QName
f [Clause]
cs SplitClause
sc = do
  [Char] -> Int -> TCMT IO Doc -> TCMT IO ()
forall (m :: * -> *).
MonadDebug m =>
[Char] -> Int -> TCMT IO Doc -> m ()
reportSDoc [Char]
"tc.cover.isCovered" Int
20 (TCMT IO Doc -> TCMT IO ()) -> TCMT IO Doc -> TCMT IO ()
forall a b. (a -> b) -> a -> b
$ [TCMT IO Doc] -> TCMT IO Doc
forall (m :: * -> *) (t :: * -> *).
(Applicative m, Foldable t) =>
t (m Doc) -> m Doc
vcat
    [ TCMT IO Doc
"isCovered"
    , Int -> TCMT IO Doc -> TCMT IO Doc
forall (m :: * -> *). Functor m => Int -> m Doc -> m Doc
nest Int
2 (TCMT IO Doc -> TCMT IO Doc) -> TCMT IO Doc -> TCMT IO Doc
forall a b. (a -> b) -> a -> b
$ [TCMT IO Doc] -> TCMT IO Doc
forall (m :: * -> *) (t :: * -> *).
(Applicative m, Foldable t) =>
t (m Doc) -> m Doc
vcat ([TCMT IO Doc] -> TCMT IO Doc) -> [TCMT IO Doc] -> TCMT IO Doc
forall a b. (a -> b) -> a -> b
$
      [ TCMT IO Doc
"f  = " TCMT IO Doc -> TCMT IO Doc -> TCMT IO Doc
forall (m :: * -> *). Applicative m => m Doc -> m Doc -> m Doc
<+> QName -> TCMT IO Doc
forall a (m :: * -> *). (PrettyTCM a, MonadPretty m) => a -> m Doc
forall (m :: * -> *). MonadPretty m => QName -> m Doc
prettyTCM QName
f
      , TCMT IO Doc
"cs = " TCMT IO Doc -> TCMT IO Doc -> TCMT IO Doc
forall (m :: * -> *). Applicative m => m Doc -> m Doc -> m Doc
<+> [TCMT IO Doc] -> TCMT IO Doc
forall (m :: * -> *) (t :: * -> *).
(Applicative m, Foldable t) =>
t (m Doc) -> m Doc
vcat ((Clause -> TCMT IO Doc) -> [Clause] -> [TCMT IO Doc]
forall a b. (a -> b) -> [a] -> [b]
map (Int -> TCMT IO Doc -> TCMT IO Doc
forall (m :: * -> *). Functor m => Int -> m Doc -> m Doc
nest Int
2 (TCMT IO Doc -> TCMT IO Doc)
-> (Clause -> TCMT IO Doc) -> Clause -> TCMT IO Doc
forall b c a. (b -> c) -> (a -> b) -> a -> c
. NamedClause -> TCMT IO Doc
forall a (m :: * -> *). (PrettyTCM a, MonadPretty m) => a -> m Doc
forall (m :: * -> *). MonadPretty m => NamedClause -> m Doc
prettyTCM (NamedClause -> TCMT IO Doc)
-> (Clause -> NamedClause) -> Clause -> TCMT IO Doc
forall b c a. (b -> c) -> (a -> b) -> a -> c
. QName -> Bool -> Clause -> NamedClause
NamedClause QName
f Bool
True) [Clause]
cs)
      , TCMT IO Doc
"sc = " TCMT IO Doc -> TCMT IO Doc -> TCMT IO Doc
forall (m :: * -> *). Applicative m => m Doc -> m Doc -> m Doc
<+> SplitClause -> TCMT IO Doc
forall a (m :: * -> *). (PrettyTCM a, MonadPretty m) => a -> m Doc
forall (m :: * -> *). MonadPretty m => SplitClause -> m Doc
prettyTCM SplitClause
sc
      ]
    ]
  -- Jesper, 2019-10: introduce trailing arguments (see #3828)
  (_ , sc') <- Bool -> SplitClause -> TCM (Telescope, SplitClause)
insertTrailingArgs Bool
True SplitClause
sc
  CoverResult { coverMissingClauses = missing } <- cover f cs sc'
  return $ null missing
 -- Andreas, 2019-08-08 and 2020-02-11
 -- If there is an error (e.g. unification error), don't report it
 -- to the user.  Rather, assume the clause is not already covered.
 TCMT IO Bool -> (TCErr -> TCMT IO Bool) -> TCMT IO Bool
forall a. TCMT IO a -> (TCErr -> TCMT IO a) -> TCMT IO a
forall e (m :: * -> *) a.
MonadError e m =>
m a -> (e -> m a) -> m a
`catchError` \ TCErr
_ -> Bool -> TCMT IO Bool
forall a. a -> TCMT IO a
forall (m :: * -> *) a. Monad m => a -> m a
return Bool
False

-- | @cover f cs (SClause _ _ ps _) = return (CoverResult splitTree used missing covering noex)@.
--   checks that the list of clauses @cs@ covers the given split clause.
--   Returns the @splitTree@, the @used@ clauses, @missing@ cases, the @covering@ clauses,
--   and the non-exact clauses @noex@.
--
--   Effect: adds missing instance clauses for @f@ to signature.
--
cover :: QName -> [Clause] -> SplitClause ->
         TCM CoverResult
cover :: QName -> [Clause] -> SplitClause -> TCM CoverResult
cover QName
f [Clause]
cs sc :: SplitClause
sc@(SClause Telescope
tel [NamedArg SplitPattern]
ps Substitution' SplitPattern
_ Map CheckpointId (Substitution' Term)
_ Maybe (Dom Type)
target) = TCM CoverResult -> TCM CoverResult
forall a. TCM a -> TCM a
updateRelevance (TCM CoverResult -> TCM CoverResult)
-> TCM CoverResult -> TCM CoverResult
forall a b. (a -> b) -> a -> b
$ do
  [Char] -> Int -> TCMT IO Doc -> TCMT IO ()
forall (m :: * -> *).
MonadDebug m =>
[Char] -> Int -> TCMT IO Doc -> m ()
reportSDoc [Char]
"tc.cover.cover" Int
10 (TCMT IO Doc -> TCMT IO ()) -> TCMT IO Doc -> TCMT IO ()
forall a b. (a -> b) -> a -> b
$ TCMT IO Doc -> TCMT IO Doc
forall (tcm :: * -> *) a.
(MonadTCEnv tcm, ReadTCState tcm) =>
tcm a -> tcm a
inTopContext (TCMT IO Doc -> TCMT IO Doc) -> TCMT IO Doc -> TCMT IO Doc
forall a b. (a -> b) -> a -> b
$ [TCMT IO Doc] -> TCMT IO Doc
forall (m :: * -> *) (t :: * -> *).
(Applicative m, Foldable t) =>
t (m Doc) -> m Doc
vcat
    [ TCMT IO Doc
"checking coverage of pattern:"
    , Int -> TCMT IO Doc -> TCMT IO Doc
forall (m :: * -> *). Functor m => Int -> m Doc -> m Doc
nest Int
2 (TCMT IO Doc -> TCMT IO Doc) -> TCMT IO Doc -> TCMT IO Doc
forall a b. (a -> b) -> a -> b
$ SplitClause -> TCMT IO Doc
forall a (m :: * -> *). (PrettyTCM a, MonadPretty m) => a -> m Doc
forall (m :: * -> *). MonadPretty m => SplitClause -> m Doc
prettyTCM SplitClause
sc
    , Int -> TCMT IO Doc -> TCMT IO Doc
forall (m :: * -> *). Functor m => Int -> m Doc -> m Doc
nest Int
2 (TCMT IO Doc -> TCMT IO Doc) -> TCMT IO Doc -> TCMT IO Doc
forall a b. (a -> b) -> a -> b
$ TCMT IO Doc
"target sort =" TCMT IO Doc -> TCMT IO Doc -> TCMT IO Doc
forall (m :: * -> *). Applicative m => m Doc -> m Doc -> m Doc
<+> do Telescope -> TCMT IO Doc -> TCMT IO Doc
forall b (m :: * -> *) a.
(AddContext b, MonadAddContext m) =>
b -> m a -> m a
forall (m :: * -> *) a.
MonadAddContext m =>
Telescope -> m a -> m a
addContext Telescope
tel (TCMT IO Doc -> TCMT IO Doc) -> TCMT IO Doc -> TCMT IO Doc
forall a b. (a -> b) -> a -> b
$ TCMT IO Doc
-> (Dom Type -> TCMT IO Doc) -> Maybe (Dom Type) -> TCMT IO Doc
forall b a. b -> (a -> b) -> Maybe a -> b
maybe ([Char] -> TCMT IO Doc
forall (m :: * -> *). Applicative m => [Char] -> m Doc
text [Char]
"<none>") (Sort -> TCMT IO Doc
forall a (m :: * -> *). (PrettyTCM a, MonadPretty m) => a -> m Doc
forall (m :: * -> *). MonadPretty m => Sort -> m Doc
prettyTCM (Sort -> TCMT IO Doc)
-> (Dom Type -> Sort) -> Dom Type -> TCMT IO Doc
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Type -> Sort
forall a. LensSort a => a -> Sort
getSort (Type -> Sort) -> (Dom Type -> Type) -> Dom Type -> Sort
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Dom Type -> Type
forall t e. Dom' t e -> e
unDom) Maybe (Dom Type)
target
    ]
  [Char] -> Int -> [Char] -> TCMT IO ()
forall (m :: * -> *).
MonadDebug m =>
[Char] -> Int -> [Char] -> m ()
reportSLn [Char]
"tc.cover.cover" Int
80 ([Char] -> TCMT IO ()) -> [Char] -> TCMT IO ()
forall a b. (a -> b) -> a -> b
$ [Char]
"raw target =\n" [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ Maybe (Dom Type) -> [Char]
forall a. Show a => a -> [Char]
show Maybe (Dom Type)
target
  [Char] -> Int -> TCMT IO () -> TCMT IO ()
forall (m :: * -> *). MonadDebug m => [Char] -> Int -> m () -> m ()
verboseS  [Char]
"tc.cover.matching" Int
20 (TCMT IO () -> TCMT IO ()) -> TCMT IO () -> TCMT IO ()
forall a b. (a -> b) -> a -> b
$ do
    [Char] -> Int -> [Char] -> TCMT IO ()
forall (m :: * -> *).
MonadDebug m =>
[Char] -> Int -> [Char] -> m ()
reportSLn [Char]
"tc.cover.matching" Int
20 ([Char] -> TCMT IO ()) -> [Char] -> TCMT IO ()
forall a b. (a -> b) -> a -> b
$ [Char]
"clauses when matching:"
    [Clause] -> (Clause -> TCMT IO ()) -> TCMT IO ()
forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
t a -> (a -> m b) -> m ()
forM_ [Clause]
cs ((Clause -> TCMT IO ()) -> TCMT IO ())
-> (Clause -> TCMT IO ()) -> TCMT IO ()
forall a b. (a -> b) -> a -> b
$ \ Clause
c -> do
      let gamma :: Telescope
gamma = Clause -> Telescope
clauseTel Clause
c
          ps :: NAPs
ps = Clause -> NAPs
namedClausePats Clause
c
      [Char] -> Int -> TCMT IO Doc -> TCMT IO ()
forall (m :: * -> *).
MonadDebug m =>
[Char] -> Int -> TCMT IO Doc -> m ()
reportSDoc [Char]
"tc.cover.matching" Int
20 (TCMT IO Doc -> TCMT IO ()) -> TCMT IO Doc -> TCMT IO ()
forall a b. (a -> b) -> a -> b
$ Telescope -> TCMT IO Doc -> TCMT IO Doc
forall b (m :: * -> *) a.
(AddContext b, MonadAddContext m) =>
b -> m a -> m a
forall (m :: * -> *) a.
MonadAddContext m =>
Telescope -> m a -> m a
addContext Telescope
gamma (TCMT IO Doc -> TCMT IO Doc) -> TCMT IO Doc -> TCMT IO Doc
forall a b. (a -> b) -> a -> b
$
          TCMT IO Doc
"ps   :" TCMT IO Doc -> TCMT IO Doc -> TCMT IO Doc
forall (m :: * -> *). Applicative m => m Doc -> m Doc -> m Doc
<+> [DeBruijnPattern] -> TCMT IO Doc
forall a (m :: * -> *). (PrettyTCM a, MonadPretty m) => a -> m Doc
forall (m :: * -> *). MonadPretty m => [DeBruijnPattern] -> m Doc
prettyTCM ((Arg (Named_ DeBruijnPattern) -> DeBruijnPattern)
-> NAPs -> [DeBruijnPattern]
forall a b. (a -> b) -> [a] -> [b]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Arg (Named_ DeBruijnPattern) -> DeBruijnPattern
forall a. NamedArg a -> a
namedArg NAPs
ps)

  [Clause]
-> [NamedArg SplitPattern]
-> TCMT IO (Match (Int, [(Int, SplitPattern)]))
forall (m :: * -> *).
PureTCM m =>
[Clause]
-> [NamedArg SplitPattern]
-> m (Match (Int, [(Int, SplitPattern)]))
match [Clause]
cs [NamedArg SplitPattern]
ps TCMT IO (Match (Int, [(Int, SplitPattern)]))
-> (Match (Int, [(Int, SplitPattern)]) -> TCM CoverResult)
-> TCM CoverResult
forall a b. TCMT IO a -> (a -> TCMT IO b) -> TCMT IO b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \case
    Yes (Int
i,[(Int, SplitPattern)]
mps) -> do
      [Char] -> Int -> [Char] -> TCMT IO ()
forall (m :: * -> *).
MonadDebug m =>
[Char] -> Int -> [Char] -> m ()
reportSLn [Char]
"tc.cover.cover" Int
10 ([Char] -> TCMT IO ()) -> [Char] -> TCMT IO ()
forall a b. (a -> b) -> a -> b
$ [Char]
"pattern covered by clause " [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ Int -> [Char]
forall a. Show a => a -> [Char]
show Int
i
      [Char] -> Int -> TCMT IO Doc -> TCMT IO ()
forall (m :: * -> *).
MonadDebug m =>
[Char] -> Int -> TCMT IO Doc -> m ()
reportSDoc [Char]
"tc.cover.cover" Int
20 (TCMT IO Doc -> TCMT IO ()) -> TCMT IO Doc -> TCMT IO ()
forall a b. (a -> b) -> a -> b
$ [Char] -> TCMT IO Doc
forall (m :: * -> *). Applicative m => [Char] -> m Doc
text [Char]
"with mps = " TCMT IO Doc -> TCMT IO Doc -> TCMT IO Doc
forall (m :: * -> *). Applicative m => m Doc -> m Doc -> m Doc
<+> do Telescope -> TCMT IO Doc -> TCMT IO Doc
forall b (m :: * -> *) a.
(AddContext b, MonadAddContext m) =>
b -> m a -> m a
forall (m :: * -> *) a.
MonadAddContext m =>
Telescope -> m a -> m a
addContext Telescope
tel (TCMT IO Doc -> TCMT IO Doc) -> TCMT IO Doc -> TCMT IO Doc
forall a b. (a -> b) -> a -> b
$ [(Int, SplitPattern)] -> TCMT IO Doc
forall (m :: * -> *) a. (Applicative m, Pretty a) => a -> m Doc
pretty [(Int, SplitPattern)]
mps
      exact <- [(Int, SplitPattern)]
-> ((Int, SplitPattern) -> TCMT IO Bool) -> TCMT IO Bool
forall (f :: * -> *) (m :: * -> *) a.
(Foldable f, Monad m) =>
f a -> (a -> m Bool) -> m Bool
allM [(Int, SplitPattern)]
mps (((Int, SplitPattern) -> TCMT IO Bool) -> TCMT IO Bool)
-> ((Int, SplitPattern) -> TCMT IO Bool) -> TCMT IO Bool
forall a b. (a -> b) -> a -> b
$ SplitPattern -> TCMT IO Bool
forall (m :: * -> *) a. HasConstInfo m => Pattern' a -> m Bool
isTrivialPattern (SplitPattern -> TCMT IO Bool)
-> ((Int, SplitPattern) -> SplitPattern)
-> (Int, SplitPattern)
-> TCMT IO Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Int, SplitPattern) -> SplitPattern
forall a b. (a, b) -> b
snd
      let cl0 = Clause -> [Clause] -> Int -> Clause
forall a. a -> [a] -> Int -> a
indexWithDefault Clause
forall a. HasCallStack => a
__IMPOSSIBLE__ [Clause]
cs Int
i
      cl <- applyCl sc cl0 mps
      return $ CoverResult
        { coverSplitTree      = SplittingDone (size tel)
        , coverUsedClauses    = singleton i
        , coverMissingClauses = []
        , coverPatterns       = [cl]
        , coverNoExactClauses = if exact then empty else singleton i
        }

    Match (Int, [(Int, SplitPattern)])
No        ->  do
      [Char] -> Int -> [Char] -> TCMT IO ()
forall (m :: * -> *).
MonadDebug m =>
[Char] -> Int -> [Char] -> m ()
reportSLn [Char]
"tc.cover" Int
20 ([Char] -> TCMT IO ()) -> [Char] -> TCMT IO ()
forall a b. (a -> b) -> a -> b
$ [Char]
"pattern is not covered"
      let infer :: Dom' a e -> Bool
infer Dom' a e
dom = Dom' a e -> Bool
forall a. LensHiding a => a -> Bool
isInstance Dom' a e
dom Bool -> Bool -> Bool
|| Maybe a -> Bool
forall a. Maybe a -> Bool
isJust (Dom' a e -> Maybe a
forall t e. Dom' t e -> Maybe t
domTactic Dom' a e
dom)
      if Bool -> (Dom Type -> Bool) -> Maybe (Dom Type) -> Bool
forall b a. b -> (a -> b) -> Maybe a -> b
maybe Bool
False Dom Type -> Bool
forall {a} {e}. Dom' a e -> Bool
infer Maybe (Dom Type)
target
        then do
          -- Ulf, 2016-10-31: For now we only infer instance clauses. It would
          -- make sense to do it also for hidden, but since the value of a
          -- hidden clause is expected to be forced by later clauses, it's too
          -- late to add it now. If it was inferrable we would have gotten a
          -- type error before getting to this point.
          -- Ulf, 2019-11-21: Also @tactic clauses.
          cl <- QName -> SplitClause -> TCM Clause
inferMissingClause QName
f SplitClause
sc
          return $ CoverResult (SplittingDone (size tel)) empty [] [cl] empty
        else do
          let ps' :: NAPs
ps' = [NamedArg SplitPattern] -> NAPs
fromSplitPatterns [NamedArg SplitPattern]
ps
          CoverResult -> TCM CoverResult
forall a. a -> TCMT IO a
forall (m :: * -> *) a. Monad m => a -> m a
return (CoverResult -> TCM CoverResult) -> CoverResult -> TCM CoverResult
forall a b. (a -> b) -> a -> b
$ SplitTree
-> IntSet
-> [(Telescope, NAPs)]
-> [Clause]
-> IntSet
-> CoverResult
CoverResult (Int -> SplitTree
forall a. Int -> SplitTree' a
SplittingDone (Telescope -> Int
forall a. Sized a => a -> Int
size Telescope
tel)) IntSet
forall a. Null a => a
empty [(Telescope
tel, NAPs
ps')] [] IntSet
forall a. Null a => a
empty

    -- We need to split!
    -- If all clauses have an unsplit copattern, we try that first.
    Block BlockedOnResult
res BlockingVars
bs -> BlockedOnResult
-> Bool
-> (SplitError -> TCM CoverResult)
-> TCM CoverResult
-> TCM CoverResult
trySplitRes BlockedOnResult
res (BlockingVars -> Bool
forall a. Null a => a -> Bool
null BlockingVars
bs) SplitError -> TCM CoverResult
forall a. SplitError -> TCM a
splitError (TCM CoverResult -> TCM CoverResult)
-> TCM CoverResult -> TCM CoverResult
forall a b. (a -> b) -> a -> b
$ do
      Bool -> TCMT IO () -> TCMT IO ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (BlockingVars -> Bool
forall a. Null a => a -> Bool
null BlockingVars
bs) TCMT IO ()
forall a. HasCallStack => a
__IMPOSSIBLE__
      -- Otherwise, if there are variables to split, we try them
      -- in the order determined by a split strategy.
      [Char] -> Int -> [Char] -> TCMT IO ()
forall (m :: * -> *).
MonadDebug m =>
[Char] -> Int -> [Char] -> m ()
reportSLn [Char]
"tc.cover.strategy" Int
20 ([Char] -> TCMT IO ()) -> [Char] -> TCMT IO ()
forall a b. (a -> b) -> a -> b
$ [Char]
"blocking vars = " [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ BlockingVars -> [Char]
forall a. Pretty a => a -> [Char]
prettyShow BlockingVars
bs
      -- xs is a non-empty lists of blocking variables
      -- try splitting on one of them
      xs <- BlockingVars -> Telescope -> TCM BlockingVars
splitStrategy BlockingVars
bs Telescope
tel
      -- Andreas, 2017-10-08, issue #2594
      -- First, try to find split order for complete coverage.
      -- If this fails, try to at least carry out the splitting to the end.
      continue xs NoAllowPartialCover $ \ SplitError
_err -> do
        BlockingVars
-> AllowPartialCover
-> (SplitError -> TCM CoverResult)
-> TCM CoverResult
continue BlockingVars
xs AllowPartialCover
YesAllowPartialCover ((SplitError -> TCM CoverResult) -> TCM CoverResult)
-> (SplitError -> TCM CoverResult) -> TCM CoverResult
forall a b. (a -> b) -> a -> b
$ \ SplitError
err -> do
          SplitError -> TCM CoverResult
forall a. SplitError -> TCM a
splitError SplitError
err
  where
    -- Andreas, 2019-08-07, issue #3966
    -- When we get a SplitError, tighten the error Range to the clauses
    -- that are still candidates for covering the SplitClause.
    splitError :: SplitError -> TCM a
    splitError :: forall a. SplitError -> TCM a
splitError = TCM a -> TCM a
forall a. TCM a -> TCM a
withRangeOfCandidateClauses (TCM a -> TCM a) -> (SplitError -> TCM a) -> SplitError -> TCM a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. TypeError -> TCM a
forall (m :: * -> *) a.
(HasCallStack, MonadTCError m) =>
TypeError -> m a
typeError (TypeError -> TCM a)
-> (SplitError -> TypeError) -> SplitError -> TCM a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. SplitError -> TypeError
SplitError

    -- This repeats the matching, but since we are crashing anyway,
    -- the extra work just to compute a better Range does not matter.
    withRangeOfCandidateClauses :: TCM a -> TCM a
    withRangeOfCandidateClauses :: forall a. TCM a -> TCM a
withRangeOfCandidateClauses TCM a
cont = do
      cands <- ((Clause, Match (DList (Int, SplitPattern))) -> Maybe Clause)
-> [(Clause, Match (DList (Int, SplitPattern)))] -> [Clause]
forall a b. (a -> Maybe b) -> [a] -> [b]
mapMaybe ((Clause -> Match (DList (Int, SplitPattern)) -> Maybe Clause)
-> (Clause, Match (DList (Int, SplitPattern))) -> Maybe Clause
forall a b c. (a -> b -> c) -> (a, b) -> c
uncurry Clause -> Match (DList (Int, SplitPattern)) -> Maybe Clause
forall a. Clause -> Match a -> Maybe Clause
notNo) ([(Clause, Match (DList (Int, SplitPattern)))] -> [Clause])
-> ([Match (DList (Int, SplitPattern))]
    -> [(Clause, Match (DList (Int, SplitPattern)))])
-> [Match (DList (Int, SplitPattern))]
-> [Clause]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Clause]
-> [Match (DList (Int, SplitPattern))]
-> [(Clause, Match (DList (Int, SplitPattern)))]
forall a b. [a] -> [b] -> [(a, b)]
zip [Clause]
cs ([Match (DList (Int, SplitPattern))] -> [Clause])
-> TCMT IO [Match (DList (Int, SplitPattern))] -> TCMT IO [Clause]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (Clause -> TCMT IO (Match (DList (Int, SplitPattern))))
-> [Clause] -> TCMT IO [Match (DList (Int, SplitPattern))]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
forall (m :: * -> *) a b. Monad m => (a -> m b) -> [a] -> m [b]
mapM ([NamedArg SplitPattern]
-> Clause -> TCMT IO (Match (DList (Int, SplitPattern)))
forall (m :: * -> *).
PureTCM m =>
[NamedArg SplitPattern]
-> Clause -> m (Match (DList (Int, SplitPattern)))
matchClause [NamedArg SplitPattern]
ps) [Clause]
cs
      setCurrentRange cands cont
      where
        notNo :: Clause -> Match a -> Maybe Clause
        notNo :: forall a. Clause -> Match a -> Maybe Clause
notNo Clause
c = \case
          Yes{}   -> Clause -> Maybe Clause
forall a. a -> Maybe a
Just Clause
c
          Block{} -> Clause -> Maybe Clause
forall a. a -> Maybe a
Just Clause
c
          No{}    -> Maybe Clause
forall a. Maybe a
Nothing

    -- Rename the variables in a telescope in accordance with their
    -- first appearance in the given NAPs. This is done to preserve
    -- variable names in IApplyConfluence error messages. Specifically,
    -- consider e.g.
    --
    --  data T : Set where
    --    x : T
    --    p : Path (Path T x x) refl refl
    --  f (p i j) = ...
    --
    -- When generating the covering clause corresponding to f's clause,
    -- the names we have in scope are i and i₁, since those are the
    -- names of both PathP binder arguments. (recall Path A x y = PathP (λ i → A) x y)
    -- So if we tried to print (Var 0 []) in the context of
    -- IApplyConfluence for that clause, what we see isn't j, it's i₁.
    --
    -- This function takes "name suggestions" from both variable
    -- patterns and IApply co/patterns, and replaces any existing names
    -- in the telescope by the name in that pattern.
    renTeleFromNap :: SplitClause -> Clause -> Telescope
    renTeleFromNap :: SplitClause -> Clause -> Telescope
renTeleFromNap SClause{scTel :: SplitClause -> Telescope
scTel = Telescope
tel, scPats :: SplitClause -> [NamedArg SplitPattern]
scPats = [NamedArg SplitPattern]
sps} Clause
clause =
      ListTel -> Telescope
telFromList (ListTel -> Telescope) -> ListTel -> Telescope
forall a b. (a -> b) -> a -> b
$ State Int ListTel -> Int -> ListTel
forall s a. State s a -> s -> a
evalState ((Dom ([Char], Type) -> StateT Int Identity (Dom ([Char], Type)))
-> ListTel -> State Int ListTel
forall (t :: * -> *) (f :: * -> *) a b.
(Traversable t, Applicative f) =>
(a -> f b) -> t a -> f (t b)
forall (f :: * -> *) a b.
Applicative f =>
(a -> f b) -> [a] -> f [b]
traverse Dom ([Char], Type) -> StateT Int Identity (Dom ([Char], Type))
upd (Telescope -> ListTel
forall t. Tele (Dom t) -> [Dom ([Char], t)]
telToList Telescope
tel)) (Int
size Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
offset)
      where
        ps :: NAPs
ps = Clause -> NAPs
namedClausePats Clause
clause
        offset :: Int
offset = Int
1 Int -> Int -> Int
forall a. Num a => a -> a -> a
+ NAPs -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length ([NamedArg SplitPattern] -> NAPs
fromSplitPatterns [NamedArg SplitPattern]
sps) Int -> Int -> Int
forall a. Num a => a -> a -> a
- NAPs -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length NAPs
ps
        -- Fold a single pattern into a map of name suggestions:
        -- In the running example above, we have
        --    f (p i@1 j@0)
        -- so the map that nameSuggest (p ...) returns is {0 → j, 1 → j}
        nameSuggest :: DeBruijnPattern -> IntMap ArgName
        nameSuggest :: DeBruijnPattern -> IntMap [Char]
nameSuggest DeBruijnPattern
ps = ((DeBruijnPattern -> IntMap [Char])
 -> DeBruijnPattern -> IntMap [Char])
-> DeBruijnPattern
-> (DeBruijnPattern -> IntMap [Char])
-> IntMap [Char]
forall a b c. (a -> b -> c) -> b -> a -> c
flip (DeBruijnPattern -> IntMap [Char])
-> DeBruijnPattern -> IntMap [Char]
forall a b m.
(PatternLike a b, Monoid m) =>
(Pattern' a -> m) -> b -> m
foldPattern DeBruijnPattern
ps ((DeBruijnPattern -> IntMap [Char]) -> IntMap [Char])
-> (DeBruijnPattern -> IntMap [Char]) -> IntMap [Char]
forall a b. (a -> b) -> a -> b
$ \case
          VarP PatternInfo
_ DBPatVar
i | DBPatVar -> [Char]
dbPatVarName DBPatVar
i [Char] -> [Char] -> Bool
forall a. Eq a => a -> a -> Bool
/= [Char]
"_" ->
            Int -> [Char] -> IntMap [Char]
forall a. Int -> a -> IntMap a
IntMap.singleton (DBPatVar -> Int
dbPatVarIndex DBPatVar
i) (DBPatVar -> [Char]
dbPatVarName DBPatVar
i)
          IApplyP PatternInfo
_ Term
_ Term
_ DBPatVar
i | DBPatVar -> [Char]
dbPatVarName DBPatVar
i [Char] -> [Char] -> Bool
forall a. Eq a => a -> a -> Bool
/= [Char]
"_" ->
            Int -> [Char] -> IntMap [Char]
forall a. Int -> a -> IntMap a
IntMap.singleton (DBPatVar -> Int
dbPatVarIndex DBPatVar
i) (DBPatVar -> [Char]
dbPatVarName DBPatVar
i)
          DeBruijnPattern
_ -> IntMap [Char]
forall a. Monoid a => a
mempty

        -- Suggestions from all patterns..
        suggestions :: IntMap [Char]
suggestions = (Arg (Named_ DeBruijnPattern) -> IntMap [Char])
-> NAPs -> IntMap [Char]
forall m a. Monoid m => (a -> m) -> [a] -> m
forall (t :: * -> *) m a.
(Foldable t, Monoid m) =>
(a -> m) -> t a -> m
foldMap (DeBruijnPattern -> IntMap [Char]
nameSuggest (DeBruijnPattern -> IntMap [Char])
-> (Arg (Named_ DeBruijnPattern) -> DeBruijnPattern)
-> Arg (Named_ DeBruijnPattern)
-> IntMap [Char]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Named_ DeBruijnPattern -> DeBruijnPattern
forall name a. Named name a -> a
namedThing (Named_ DeBruijnPattern -> DeBruijnPattern)
-> (Arg (Named_ DeBruijnPattern) -> Named_ DeBruijnPattern)
-> Arg (Named_ DeBruijnPattern)
-> DeBruijnPattern
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Arg (Named_ DeBruijnPattern) -> Named_ DeBruijnPattern
forall e. Arg e -> e
unArg) NAPs
ps

        -- The state will start counting from (length Γ - 1), which is
        -- the *highest* variable index, i.e. the index of the variable
        -- with level 0. Instead of doing a lot of de Bruijn arithmetic
        -- + recursion, traverse handles iteration and the State handles
        -- counting down.
        size :: Int
size = ListTel -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length (Telescope -> ListTel
forall t. Tele (Dom t) -> [Dom ([Char], t)]
telToList Telescope
tel)

        upd :: Dom (ArgName , Type) -> State Int (Dom (ArgName , Type))
        upd :: Dom ([Char], Type) -> StateT Int Identity (Dom ([Char], Type))
upd Dom ([Char], Type)
dom = (Int -> (Dom ([Char], Type), Int))
-> StateT Int Identity (Dom ([Char], Type))
forall a. (Int -> (a, Int)) -> StateT Int Identity a
forall s (m :: * -> *) a. MonadState s m => (s -> (a, s)) -> m a
state ((Int -> (Dom ([Char], Type), Int))
 -> StateT Int Identity (Dom ([Char], Type)))
-> (Int -> (Dom ([Char], Type), Int))
-> StateT Int Identity (Dom ([Char], Type))
forall a b. (a -> b) -> a -> b
$ \Int
s -> do
          case Int -> IntMap [Char] -> Maybe [Char]
forall a. Int -> IntMap a -> Maybe a
IntMap.lookup Int
s IntMap [Char]
suggestions of
            Just [Char]
nm' -> ( Dom ([Char], Type)
dom{ domName = Just (WithOrigin CaseSplit (unranged nm'))
                             , unDom = (nm' , snd (unDom dom))
                             } , Int
s Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1)
            Maybe [Char]
Nothing -> (Dom ([Char], Type)
dom , Int
s Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1)

    applyCl :: SplitClause -> Clause -> [(Nat, SplitPattern)] -> TCM Clause
    applyCl :: SplitClause -> Clause -> [(Int, SplitPattern)] -> TCM Clause
applyCl sc :: SplitClause
sc@SClause{scTel :: SplitClause -> Telescope
scTel = Telescope
pretel, scPats :: SplitClause -> [NamedArg SplitPattern]
scPats = [NamedArg SplitPattern]
sps} Clause
cl [(Int, SplitPattern)]
mps
        | Telescope
tel <- SplitClause -> Clause -> Telescope
renTeleFromNap SplitClause
sc Clause
cl = Telescope -> TCM Clause -> TCM Clause
forall b (m :: * -> *) a.
(AddContext b, MonadAddContext m) =>
b -> m a -> m a
forall (m :: * -> *) a.
MonadAddContext m =>
Telescope -> m a -> m a
addContext Telescope
tel (TCM Clause -> TCM Clause) -> TCM Clause -> TCM Clause
forall a b. (a -> b) -> a -> b
$ do
        let ps :: NAPs
ps = Clause -> NAPs
namedClausePats Clause
cl
        [Char] -> Int -> TCMT IO Doc -> TCMT IO ()
forall (m :: * -> *).
MonadDebug m =>
[Char] -> Int -> TCMT IO Doc -> m ()
reportSDoc [Char]
"tc.cover.applyCl" Int
40 (TCMT IO Doc -> TCMT IO ()) -> TCMT IO Doc -> TCMT IO ()
forall a b. (a -> b) -> a -> b
$ TCMT IO Doc
"applyCl"
        [Char] -> Int -> TCMT IO Doc -> TCMT IO ()
forall (m :: * -> *).
MonadDebug m =>
[Char] -> Int -> TCMT IO Doc -> m ()
reportSDoc [Char]
"tc.cover.applyCl" Int
40 (TCMT IO Doc -> TCMT IO ()) -> TCMT IO Doc -> TCMT IO ()
forall a b. (a -> b) -> a -> b
$ TCMT IO Doc
"pretel =" TCMT IO Doc -> TCMT IO Doc -> TCMT IO Doc
forall (m :: * -> *). Applicative m => m Doc -> m Doc -> m Doc
<+> Telescope -> TCMT IO Doc
forall (m :: * -> *) a. (Applicative m, Pretty a) => a -> m Doc
pretty Telescope
pretel
        [Char] -> Int -> TCMT IO Doc -> TCMT IO ()
forall (m :: * -> *).
MonadDebug m =>
[Char] -> Int -> TCMT IO Doc -> m ()
reportSDoc [Char]
"tc.cover.applyCl" Int
40 (TCMT IO Doc -> TCMT IO ()) -> TCMT IO Doc -> TCMT IO ()
forall a b. (a -> b) -> a -> b
$ TCMT IO Doc
"tel    =" TCMT IO Doc -> TCMT IO Doc -> TCMT IO Doc
forall (m :: * -> *). Applicative m => m Doc -> m Doc -> m Doc
<+> Telescope -> TCMT IO Doc
forall (m :: * -> *) a. (Applicative m, Pretty a) => a -> m Doc
pretty Telescope
tel
        [Char] -> Int -> TCMT IO Doc -> TCMT IO ()
forall (m :: * -> *).
MonadDebug m =>
[Char] -> Int -> TCMT IO Doc -> m ()
reportSDoc [Char]
"tc.cover.applyCl" Int
40 (TCMT IO Doc -> TCMT IO ()) -> TCMT IO Doc -> TCMT IO ()
forall a b. (a -> b) -> a -> b
$ TCMT IO Doc
"ps     =" TCMT IO Doc -> TCMT IO Doc -> TCMT IO Doc
forall (m :: * -> *). Applicative m => m Doc -> m Doc -> m Doc
<+> NAPs -> TCMT IO Doc
forall (m :: * -> *) a. (Applicative m, Pretty a) => a -> m Doc
pretty NAPs
ps
        [Char] -> Int -> TCMT IO Doc -> TCMT IO ()
forall (m :: * -> *).
MonadDebug m =>
[Char] -> Int -> TCMT IO Doc -> m ()
reportSDoc [Char]
"tc.cover.applyCl" Int
40 (TCMT IO Doc -> TCMT IO ()) -> TCMT IO Doc -> TCMT IO ()
forall a b. (a -> b) -> a -> b
$ TCMT IO Doc
"mps    =" TCMT IO Doc -> TCMT IO Doc -> TCMT IO Doc
forall (m :: * -> *). Applicative m => m Doc -> m Doc -> m Doc
<+> [(Int, SplitPattern)] -> TCMT IO Doc
forall (m :: * -> *) a. (Applicative m, Pretty a) => a -> m Doc
pretty [(Int, SplitPattern)]
mps
        [Char] -> Int -> TCMT IO Doc -> TCMT IO ()
forall (m :: * -> *).
MonadDebug m =>
[Char] -> Int -> TCMT IO Doc -> m ()
reportSDoc [Char]
"tc.cover.applyCl" Int
40 (TCMT IO Doc -> TCMT IO ()) -> TCMT IO Doc -> TCMT IO ()
forall a b. (a -> b) -> a -> b
$ TCMT IO Doc
"s      =" TCMT IO Doc -> TCMT IO Doc -> TCMT IO Doc
forall (m :: * -> *). Applicative m => m Doc -> m Doc -> m Doc
<+> PatternSubstitution -> TCMT IO Doc
forall (m :: * -> *) a. (Applicative m, Pretty a) => a -> m Doc
pretty PatternSubstitution
s
        [Char] -> Int -> TCMT IO Doc -> TCMT IO ()
forall (m :: * -> *).
MonadDebug m =>
[Char] -> Int -> TCMT IO Doc -> m ()
reportSDoc [Char]
"tc.cover.applyCl" Int
40 (TCMT IO Doc -> TCMT IO ()) -> TCMT IO Doc -> TCMT IO ()
forall a b. (a -> b) -> a -> b
$ TCMT IO Doc
"ps[s]  =" TCMT IO Doc -> TCMT IO Doc -> TCMT IO Doc
forall (m :: * -> *). Applicative m => m Doc -> m Doc -> m Doc
<+> NAPs -> TCMT IO Doc
forall (m :: * -> *) a. (Applicative m, Pretty a) => a -> m Doc
pretty (PatternSubstitution
Substitution' (SubstArg NAPs)
s Substitution' (SubstArg NAPs) -> NAPs -> NAPs
forall a. Subst a => Substitution' (SubstArg a) -> a -> a
`applySubst` NAPs
ps)

        -- If a matching clause has fewer patterns than the split
        -- clause we ought to copy over the extra ones.
        -- e.g. if the user wrote:
        --
        --   bar : Bool -> Bool
        --   bar false = false
        --   bar = \ _ -> true
        --
        -- then for the second clause the @extra@ patterns will be @[true]@.

        let extra :: NAPs
extra = Int -> NAPs -> NAPs
forall a. Int -> [a] -> [a]
drop (NAPs -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length NAPs
ps) (NAPs -> NAPs) -> NAPs -> NAPs
forall a b. (a -> b) -> a -> b
$ [NamedArg SplitPattern] -> NAPs
fromSplitPatterns [NamedArg SplitPattern]
sps
            n_extra :: Int
n_extra = NAPs -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length NAPs
extra

        [Char] -> Int -> TCMT IO Doc -> TCMT IO ()
forall (m :: * -> *).
MonadDebug m =>
[Char] -> Int -> TCMT IO Doc -> m ()
reportSDoc [Char]
"tc.cover.applyCl" Int
40 (TCMT IO Doc -> TCMT IO ()) -> TCMT IO Doc -> TCMT IO ()
forall a b. (a -> b) -> a -> b
$ TCMT IO Doc
"extra  =" TCMT IO Doc -> TCMT IO Doc -> TCMT IO Doc
forall (m :: * -> *). Applicative m => m Doc -> m Doc -> m Doc
<+> NAPs -> TCMT IO Doc
forall (m :: * -> *) a. (Applicative m, Pretty a) => a -> m Doc
pretty NAPs
extra

        -- When we add the extra patterns we also update the type
        -- and the body of the clause.

        mtv <- ((Arg Type -> TCMT IO (Arg (TelV Type)))
-> Maybe (Arg Type) -> TCMT IO (Maybe (Arg (TelV Type)))
forall (t :: * -> *) (f :: * -> *) a b.
(Traversable t, Applicative f) =>
(a -> f b) -> t a -> f (t b)
forall (f :: * -> *) a b.
Applicative f =>
(a -> f b) -> Maybe a -> f (Maybe b)
traverse ((Arg Type -> TCMT IO (Arg (TelV Type)))
 -> Maybe (Arg Type) -> TCMT IO (Maybe (Arg (TelV Type))))
-> ((Type -> TCMT IO (TelV Type))
    -> Arg Type -> TCMT IO (Arg (TelV Type)))
-> (Type -> TCMT IO (TelV Type))
-> Maybe (Arg Type)
-> TCMT IO (Maybe (Arg (TelV Type)))
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Type -> TCMT IO (TelV Type))
-> Arg Type -> TCMT IO (Arg (TelV Type))
forall (t :: * -> *) (f :: * -> *) a b.
(Traversable t, Applicative f) =>
(a -> f b) -> t a -> f (t b)
forall (f :: * -> *) a b.
Applicative f =>
(a -> f b) -> Arg a -> f (Arg b)
traverse) (Int -> Type -> TCMT IO (TelV Type)
forall (m :: * -> *). PureTCM m => Int -> Type -> m (TelV Type)
telViewUpToPath Int
n_extra) (Maybe (Arg Type) -> TCMT IO (Maybe (Arg (TelV Type))))
-> Maybe (Arg Type) -> TCMT IO (Maybe (Arg (TelV Type)))
forall a b. (a -> b) -> a -> b
$ Clause -> Maybe (Arg Type)
clauseType Clause
cl
        let ty = ((Arg (TelV Type) -> Arg Type)
-> Maybe (Arg (TelV Type)) -> Maybe (Arg Type)
forall a b. (a -> b) -> Maybe a -> Maybe b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ((Arg (TelV Type) -> Arg Type)
 -> Maybe (Arg (TelV Type)) -> Maybe (Arg Type))
-> ((TelV Type -> Type) -> Arg (TelV Type) -> Arg Type)
-> (TelV Type -> Type)
-> Maybe (Arg (TelV Type))
-> Maybe (Arg Type)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (TelV Type -> Type) -> Arg (TelV Type) -> Arg Type
forall a b. (a -> b) -> Arg a -> Arg b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap) (([DeBruijnPattern] -> PatternSubstitution
forall a. DeBruijn a => [a] -> Substitution' a
parallelS ([DeBruijnPattern] -> [DeBruijnPattern]
forall a. [a] -> [a]
reverse ([DeBruijnPattern] -> [DeBruijnPattern])
-> [DeBruijnPattern] -> [DeBruijnPattern]
forall a b. (a -> b) -> a -> b
$ (Arg (Named_ DeBruijnPattern) -> DeBruijnPattern)
-> NAPs -> [DeBruijnPattern]
forall a b. (a -> b) -> [a] -> [b]
map Arg (Named_ DeBruijnPattern) -> DeBruijnPattern
forall a. NamedArg a -> a
namedArg NAPs
extra) PatternSubstitution -> PatternSubstitution -> PatternSubstitution
forall a.
EndoSubst a =>
Substitution' a -> Substitution' a -> Substitution' a
`composeS` Int -> PatternSubstitution -> PatternSubstitution
forall a. Int -> Substitution' a -> Substitution' a
liftS Int
n_extra PatternSubstitution
s PatternSubstitution -> Type -> Type
forall a. TermSubst a => PatternSubstitution -> a -> a
`applyPatSubst`) (Type -> Type) -> (TelV Type -> Type) -> TelV Type -> Type
forall b c a. (b -> c) -> (a -> b) -> a -> c
. TelV Type -> Type
forall a. TelV a -> a
theCore) Maybe (Arg (TelV Type))
mtv

        reportSDoc "tc.cover.applyCl" 40 $ "new ty =" <+> pretty ty

        return $
             Clause { clauseLHSRange  = clauseLHSRange cl
                    , clauseFullRange = clauseFullRange cl
                    , clauseTel       = tel
                    , namedClausePats = (s `applySubst` ps) ++ extra
                    , clauseBody      = (`applyE` patternsToElims extra) . (s `applyPatSubst`) <$> clauseBody cl
                    , clauseType      = ty
                    , clauseCatchall    = clauseCatchall cl
                    , clauseExact       = clauseExact cl
                    , clauseRecursive   = clauseRecursive cl
                    , clauseUnreachable = clauseUnreachable cl
                    , clauseEllipsis    = clauseEllipsis cl
                    , clauseWhereModule = clauseWhereModule cl
                    }
      where
      mps' :: Map Int DeBruijnPattern
mps' =
        [(Int, DeBruijnPattern)] -> Map Int DeBruijnPattern
forall k a. Ord k => [(k, a)] -> Map k a
Map.fromList ([(Int, DeBruijnPattern)] -> Map Int DeBruijnPattern)
-> [(Int, DeBruijnPattern)] -> Map Int DeBruijnPattern
forall a b. (a -> b) -> a -> b
$
        ((Int, SplitPattern) -> (Int, DeBruijnPattern))
-> [(Int, SplitPattern)] -> [(Int, DeBruijnPattern)]
forall a b. (a -> b) -> [a] -> [b]
map ((SplitPattern -> DeBruijnPattern)
-> (Int, SplitPattern) -> (Int, DeBruijnPattern)
forall b d a. (b -> d) -> (a, b) -> (a, d)
mapSnd (Arg (Named_ DeBruijnPattern) -> DeBruijnPattern
forall a. NamedArg a -> a
namedArg (Arg (Named_ DeBruijnPattern) -> DeBruijnPattern)
-> (SplitPattern -> Arg (Named_ DeBruijnPattern))
-> SplitPattern
-> DeBruijnPattern
forall b c a. (b -> c) -> (a -> b) -> a -> c
. NamedArg SplitPattern -> Arg (Named_ DeBruijnPattern)
fromSplitPattern (NamedArg SplitPattern -> Arg (Named_ DeBruijnPattern))
-> (SplitPattern -> NamedArg SplitPattern)
-> SplitPattern
-> Arg (Named_ DeBruijnPattern)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. SplitPattern -> NamedArg SplitPattern
forall a. a -> NamedArg a
defaultNamedArg)) [(Int, SplitPattern)]
mps
      s :: PatternSubstitution
s = [DeBruijnPattern] -> PatternSubstitution
forall a. DeBruijn a => [a] -> Substitution' a
parallelS ([Int] -> (Int -> DeBruijnPattern) -> [DeBruijnPattern]
forall (m :: * -> *) a b. Functor m => m a -> (a -> b) -> m b
for (case Map Int DeBruijnPattern -> Maybe (Int, DeBruijnPattern)
forall k a. Map k a -> Maybe (k, a)
Map.lookupMax Map Int DeBruijnPattern
mps' of
                            Maybe (Int, DeBruijnPattern)
Nothing     -> []
                            Just (Int
i, DeBruijnPattern
_) -> [Int
0..Int
i]) ((Int -> DeBruijnPattern) -> [DeBruijnPattern])
-> (Int -> DeBruijnPattern) -> [DeBruijnPattern]
forall a b. (a -> b) -> a -> b
$ \ Int
i ->
                     DeBruijnPattern -> Maybe DeBruijnPattern -> DeBruijnPattern
forall a. a -> Maybe a -> a
fromMaybe (Int -> DeBruijnPattern
forall a. DeBruijn a => Int -> a
deBruijnVar Int
i) (Int -> Map Int DeBruijnPattern -> Maybe DeBruijnPattern
forall k a. Ord k => k -> Map k a -> Maybe a
Map.lookup Int
i Map Int DeBruijnPattern
mps'))

    updateRelevance :: TCM a -> TCM a
    updateRelevance :: forall a. TCM a -> TCM a
updateRelevance TCM a
cont =
      -- Don't do anything if there is no target type info.
      Maybe (Dom Type) -> TCM a -> (Dom Type -> TCM a) -> TCM a
forall a b. Maybe a -> b -> (a -> b) -> b
caseMaybe Maybe (Dom Type)
target TCM a
cont ((Dom Type -> TCM a) -> TCM a) -> (Dom Type -> TCM a) -> TCM a
forall a b. (a -> b) -> a -> b
$ \ Dom Type
b -> do
        -- TODO (2018-10-16): if proofs get erased in the compiler, also wake erased vars!
        let m :: Modality
m = Dom Type -> Modality
forall a. LensModality a => a -> Modality
getModality Dom Type
b
        Modality -> TCM a -> TCM a
forall (tcm :: * -> *) m a.
(MonadTCEnv tcm, LensModality m) =>
m -> tcm a -> tcm a
applyModalityToContext Modality
m TCM a
cont

    continue
      :: [BlockingVar]
      -> AllowPartialCover
      -> (SplitError -> TCM CoverResult)
      -> TCM CoverResult
    continue :: BlockingVars
-> AllowPartialCover
-> (SplitError -> TCM CoverResult)
-> TCM CoverResult
continue BlockingVars
xs AllowPartialCover
allowPartialCover SplitError -> TCM CoverResult
handle = do
      r <- (BlockingVar
 -> TCMT IO (Either SplitError (Covering, BlockingVar)))
-> BlockingVars
-> TCMT IO (Either SplitError (Covering, BlockingVar))
forall (m :: * -> *) a err b.
Monad m =>
(a -> m (Either err b)) -> [a] -> m (Either err b)
altM1 (\ BlockingVar
x -> (Covering -> (Covering, BlockingVar))
-> Either SplitError Covering
-> Either SplitError (Covering, BlockingVar)
forall a b. (a -> b) -> Either SplitError a -> Either SplitError b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (,BlockingVar
x) (Either SplitError Covering
 -> Either SplitError (Covering, BlockingVar))
-> TCMT IO (Either SplitError Covering)
-> TCMT IO (Either SplitError (Covering, BlockingVar))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Induction
-> AllowPartialCover
-> SplitClause
-> BlockingVar
-> TCMT IO (Either SplitError Covering)
split Induction
Inductive AllowPartialCover
allowPartialCover SplitClause
sc BlockingVar
x) BlockingVars
xs
      case r of
        Left SplitError
err -> SplitError -> TCM CoverResult
handle SplitError
err
        -- If we get the empty covering, we have reached an impossible case
        -- and are done.
        Right (Covering Arg Int
n [], BlockingVar
_) ->
         do
          -- TODO Andrea: I guess an empty pattern is not part of the cover?
          let qs :: [a]
qs = []
          CoverResult -> TCM CoverResult
forall a. a -> TCMT IO a
forall (m :: * -> *) a. Monad m => a -> m a
return (CoverResult -> TCM CoverResult) -> CoverResult -> TCM CoverResult
forall a b. (a -> b) -> a -> b
$ SplitTree
-> IntSet
-> [(Telescope, NAPs)]
-> [Clause]
-> IntSet
-> CoverResult
CoverResult (Int -> SplitTree
forall a. Int -> SplitTree' a
SplittingDone (Telescope -> Int
forall a. Sized a => a -> Int
size Telescope
tel)) IntSet
forall a. Null a => a
empty [] [Clause]
forall a. [a]
qs IntSet
forall a. Null a => a
empty
        Right (Covering Arg Int
n [(SplitTag, (SplitClause, IInfo))]
scs', BlockingVar
x) -> do
          let scs :: [(SplitTag, SplitClause)]
scs = ((SplitTag, (SplitClause, IInfo)) -> (SplitTag, SplitClause))
-> [(SplitTag, (SplitClause, IInfo))] -> [(SplitTag, SplitClause)]
forall a b. (a -> b) -> [a] -> [b]
map (\(SplitTag
t,(SplitClause
sc,IInfo
i)) -> (SplitTag
t,SplitClause
sc)) [(SplitTag, (SplitClause, IInfo))]
scs'

          (results_trX, cs) <- QName
-> Arg Int
-> BlockingVar
-> SplitClause
-> [(SplitTag, (SplitClause, IInfo))]
-> [Clause]
-> TCM ([(SplitTag, CoverResult)], [Clause])
createMissingIndexedClauses QName
f Arg Int
n BlockingVar
x SplitClause
sc [(SplitTag, (SplitClause, IInfo))]
scs' [Clause]
cs
          (scs, cs, results_hc) <- do
            let fallback = ([(SplitTag, SplitClause)], [Clause], [(SplitTag, CoverResult)])
-> TCMT
     IO ([(SplitTag, SplitClause)], [Clause], [(SplitTag, CoverResult)])
forall a. a -> TCMT IO a
forall (m :: * -> *) a. Monad m => a -> m a
return ([(SplitTag, SplitClause)]
scs, [Clause]
cs, [])
            caseMaybeM (getPrimitiveName' builtinHComp) fallback $ \ QName
comp -> do
            let isComp :: SplitTag -> Bool
isComp = \case
                  SplitCon QName
c -> QName
comp QName -> QName -> Bool
forall a. Eq a => a -> a -> Bool
== QName
c
                  SplitTag
_ -> Bool
False
            Maybe (SplitTag, SplitClause)
-> TCMT
     IO ([(SplitTag, SplitClause)], [Clause], [(SplitTag, CoverResult)])
-> ((SplitTag, SplitClause)
    -> TCMT
         IO
         ([(SplitTag, SplitClause)], [Clause], [(SplitTag, CoverResult)]))
-> TCMT
     IO ([(SplitTag, SplitClause)], [Clause], [(SplitTag, CoverResult)])
forall a b. Maybe a -> b -> (a -> b) -> b
caseMaybe (((SplitTag, SplitClause) -> Bool)
-> [(SplitTag, SplitClause)] -> Maybe (SplitTag, SplitClause)
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Maybe a
List.find (SplitTag -> Bool
isComp (SplitTag -> Bool)
-> ((SplitTag, SplitClause) -> SplitTag)
-> (SplitTag, SplitClause)
-> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (SplitTag, SplitClause) -> SplitTag
forall a b. (a, b) -> a
fst) [(SplitTag, SplitClause)]
scs) TCMT
  IO ([(SplitTag, SplitClause)], [Clause], [(SplitTag, CoverResult)])
fallback (((SplitTag, SplitClause)
  -> TCMT
       IO
       ([(SplitTag, SplitClause)], [Clause], [(SplitTag, CoverResult)]))
 -> TCMT
      IO
      ([(SplitTag, SplitClause)], [Clause], [(SplitTag, CoverResult)]))
-> ((SplitTag, SplitClause)
    -> TCMT
         IO
         ([(SplitTag, SplitClause)], [Clause], [(SplitTag, CoverResult)]))
-> TCMT
     IO ([(SplitTag, SplitClause)], [Clause], [(SplitTag, CoverResult)])
forall a b. (a -> b) -> a -> b
$ \ (SplitTag
sp, SplitClause
newSc) -> do
            (res,cs') <- QName
-> Arg Int
-> BlockingVar
-> SplitClause
-> SplitClause
-> [Clause]
-> TCM ([(SplitTag, CoverResult)], [Clause])
createMissingHCompClause QName
f Arg Int
n BlockingVar
x SplitClause
sc SplitClause
newSc [Clause]
cs
            let scs2 = ((SplitTag, SplitClause) -> Bool)
-> [(SplitTag, SplitClause)] -> [(SplitTag, SplitClause)]
forall a. (a -> Bool) -> [a] -> [a]
filter (Bool -> Bool
not (Bool -> Bool)
-> ((SplitTag, SplitClause) -> Bool)
-> (SplitTag, SplitClause)
-> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. SplitTag -> Bool
isComp (SplitTag -> Bool)
-> ((SplitTag, SplitClause) -> SplitTag)
-> (SplitTag, SplitClause)
-> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (SplitTag, SplitClause) -> SplitTag
forall a b. (a, b) -> a
fst) [(SplitTag, SplitClause)]
scs
            return (scs2,cs',res)
          let results_extra = [(SplitTag, CoverResult)]
results_hc [(SplitTag, CoverResult)]
-> [(SplitTag, CoverResult)] -> [(SplitTag, CoverResult)]
forall a. [a] -> [a] -> [a]
++ [(SplitTag, CoverResult)]
results_trX
              trees_extra = ((SplitTag, CoverResult) -> (SplitTag, SplitTree))
-> [(SplitTag, CoverResult)] -> [(SplitTag, SplitTree)]
forall a b. (a -> b) -> [a] -> [b]
map (\(SplitTag
sp,CoverResult
cr) -> (SplitTag
sp, CoverResult -> SplitTree
coverSplitTree CoverResult
cr)) [(SplitTag, CoverResult)]
results_extra

          results <- (++ map snd (results_extra)) <$> mapM ((cover f cs) . snd) scs
          let trees = (CoverResult -> SplitTree) -> [CoverResult] -> [SplitTree]
forall a b. (a -> b) -> [a] -> [b]
map CoverResult -> SplitTree
coverSplitTree      [CoverResult]
results
              useds = (CoverResult -> IntSet) -> [CoverResult] -> [IntSet]
forall a b. (a -> b) -> [a] -> [b]
map CoverResult -> IntSet
coverUsedClauses    [CoverResult]
results
              psss  = (CoverResult -> [(Telescope, NAPs)])
-> [CoverResult] -> [[(Telescope, NAPs)]]
forall a b. (a -> b) -> [a] -> [b]
map CoverResult -> [(Telescope, NAPs)]
coverMissingClauses [CoverResult]
results
              qsss  = (CoverResult -> [Clause]) -> [CoverResult] -> [[Clause]]
forall a b. (a -> b) -> [a] -> [b]
map CoverResult -> [Clause]
coverPatterns       [CoverResult]
results
              noex  = (CoverResult -> IntSet) -> [CoverResult] -> [IntSet]
forall a b. (a -> b) -> [a] -> [b]
map CoverResult -> IntSet
coverNoExactClauses [CoverResult]
results
          -- Jesper, 2016-03-10  We need to remember which variables were
          -- eta-expanded by the unifier in order to generate a correct split
          -- tree (see Issue 1872).
          reportSDoc "tc.cover.split.eta" 60 $ vcat
            [ "etaRecordSplits"
            , nest 2 $ vcat
              [ "n   = " <+> text (show n)
              , "scs = " <+> prettyTCM scs
              , "ps  = " <+> prettyTCMPatternList (fromSplitPatterns ps)
              ]
            ]
          let trees' = ((SplitTag, SplitClause) -> SplitTree -> (SplitTag, SplitTree))
-> [(SplitTag, SplitClause)]
-> [SplitTree]
-> [(SplitTag, SplitTree)]
forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
zipWith (Int
-> [NamedArg SplitPattern]
-> (SplitTag, SplitClause)
-> SplitTree
-> (SplitTag, SplitTree)
etaRecordSplits (Arg Int -> Int
forall e. Arg e -> e
unArg Arg Int
n) [NamedArg SplitPattern]
ps) [(SplitTag, SplitClause)]
scs [SplitTree]
trees
              tree   = Arg Int -> LazySplit -> [(SplitTag, SplitTree)] -> SplitTree
forall a. Arg Int -> LazySplit -> SplitTrees' a -> SplitTree' a
SplitAt Arg Int
n LazySplit
StrictSplit ([(SplitTag, SplitTree)]
trees' [(SplitTag, SplitTree)]
-> [(SplitTag, SplitTree)] -> [(SplitTag, SplitTree)]
forall a. [a] -> [a] -> [a]
++ [(SplitTag, SplitTree)]
trees_extra) -- TODO: Lazy?
          return $ CoverResult tree (IntSet.unions useds) (concat psss) (concat qsss) (IntSet.unions noex)

    -- Try to split result
    trySplitRes
      :: BlockedOnResult                  -- Are we blocked on the result?
      -> Bool                             -- Is this the last thing we try?
      -> (SplitError -> TCM CoverResult)  -- Handler for 'SplitError'
      -> TCM CoverResult                  -- Continuation
      -> TCM CoverResult
    -- not blocked on result: try regular splits
    trySplitRes :: BlockedOnResult
-> Bool
-> (SplitError -> TCM CoverResult)
-> TCM CoverResult
-> TCM CoverResult
trySplitRes BlockedOnResult
NotBlockedOnResult Bool
finalSplit SplitError -> TCM CoverResult
splitError TCM CoverResult
cont
      | Bool
finalSplit = TCM CoverResult
forall a. HasCallStack => a
__IMPOSSIBLE__ -- there must be *some* reason we are blocked
      | Bool
otherwise  = TCM CoverResult
cont
    -- blocked on arguments that are not yet introduced:

    -- we must split on a variable so that the target type becomes a pi type
    trySplitRes (BlockedOnApply ApplyOrIApply
IsApply) Bool
finalSplit SplitError -> TCM CoverResult
splitError TCM CoverResult
cont = do
      -- Andreas, 2021-12-31, issue #5712.
      -- If there is a tactic to solve the clause, we might not have inserted
      -- trailing args (due to #5358).  Now we force it!
      (tel, sc') <- Bool -> SplitClause -> TCM (Telescope, SplitClause)
insertTrailingArgs Bool
True SplitClause
sc
      if null tel then
        if finalSplit then __IMPOSSIBLE__ -- already ruled out by lhs checker
        else cont
      else cover f cs sc'

    -- ...or it was an IApply pattern, so we might just need to introduce the variable now.
    trySplitRes (BlockedOnApply ApplyOrIApply
IsIApply) Bool
finalSplit SplitError -> TCM CoverResult
splitError TCM CoverResult
cont
       = do
         TCMT IO (Maybe SplitClause)
-> TCM CoverResult
-> (SplitClause -> TCM CoverResult)
-> TCM CoverResult
forall (m :: * -> *) a b.
Monad m =>
m (Maybe a) -> m b -> (a -> m b) -> m b
caseMaybeM (QName -> SplitClause -> TCMT IO (Maybe SplitClause)
splitResultPath QName
f SplitClause
sc) TCM CoverResult
fallback ((SplitClause -> TCM CoverResult) -> TCM CoverResult)
-> (SplitClause -> TCM CoverResult) -> TCM CoverResult
forall a b. (a -> b) -> a -> b
$ (QName -> [Clause] -> SplitClause -> TCM CoverResult
cover QName
f [Clause]
cs (SplitClause -> TCM CoverResult)
-> ((Telescope, SplitClause) -> SplitClause)
-> (Telescope, SplitClause)
-> TCM CoverResult
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Telescope, SplitClause) -> SplitClause
forall a b. (a, b) -> b
snd) ((Telescope, SplitClause) -> TCM CoverResult)
-> (SplitClause -> TCM (Telescope, SplitClause))
-> SplitClause
-> TCM CoverResult
forall (m :: * -> *) b c a.
Monad m =>
(b -> m c) -> (a -> m b) -> a -> m c
<=< Bool -> SplitClause -> TCM (Telescope, SplitClause)
insertTrailingArgs Bool
False
      where
        fallback :: TCM CoverResult
fallback | Bool
finalSplit = TCM CoverResult
forall a. HasCallStack => a
__IMPOSSIBLE__ -- already ruled out by lhs checker?
                 | Bool
otherwise  = TCM CoverResult
cont

    -- blocked on result but there are catchalls:
    -- try regular splits if there are any, or else throw an error,
    -- this is nicer than continuing and reporting unreachable clauses
    -- (see issue #2833)
    trySplitRes (BlockedOnProj Bool
True) Bool
finalSplit SplitError -> TCM CoverResult
splitError TCM CoverResult
cont
      | Bool
finalSplit = SplitError -> TCM CoverResult
splitError SplitError
CosplitCatchall
      | Bool
otherwise  = TCM CoverResult
cont
    -- all clauses have an unsplit copattern: try to split
    trySplitRes (BlockedOnProj Bool
False) Bool
finalSplit SplitError -> TCM CoverResult
splitError TCM CoverResult
cont = do
      [Char] -> Int -> [Char] -> TCMT IO ()
forall (m :: * -> *).
MonadDebug m =>
[Char] -> Int -> [Char] -> m ()
reportSLn [Char]
"tc.cover" Int
20 ([Char] -> TCMT IO ()) -> [Char] -> TCMT IO ()
forall a b. (a -> b) -> a -> b
$ [Char]
"blocked by projection pattern"
      -- forM is a monadic map over a Maybe here
      mcov <- QName -> SplitClause -> TCMT IO (Either SplitError Covering)
splitResultRecord QName
f SplitClause
sc
      case mcov of
        Left SplitError
err
          | Bool
finalSplit -> SplitError -> TCM CoverResult
splitError SplitError
err
          | Bool
otherwise  -> TCM CoverResult
cont
        Right (Covering Arg Int
n [(SplitTag, (SplitClause, IInfo))]
scs) -> do
          -- If result splitting was successful, continue coverage checking.
          (projs, results) <- [(SplitTag, CoverResult)] -> ([SplitTag], [CoverResult])
forall a b. [(a, b)] -> ([a], [b])
unzip ([(SplitTag, CoverResult)] -> ([SplitTag], [CoverResult]))
-> TCMT IO [(SplitTag, CoverResult)]
-> TCMT IO ([SplitTag], [CoverResult])
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> do
            ((SplitTag, SplitClause) -> TCMT IO (SplitTag, CoverResult))
-> [(SplitTag, SplitClause)] -> TCMT IO [(SplitTag, CoverResult)]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
forall (m :: * -> *) a b. Monad m => (a -> m b) -> [a] -> m [b]
mapM ((SplitClause -> TCM CoverResult)
-> (SplitTag, SplitClause) -> TCMT IO (SplitTag, CoverResult)
forall (t :: * -> *) (m :: * -> *) a b.
(Decoration t, Functor m) =>
(a -> m b) -> t a -> m (t b)
forall (m :: * -> *) a b.
Functor m =>
(a -> m b) -> (SplitTag, a) -> m (SplitTag, b)
traverseF ((SplitClause -> TCM CoverResult)
 -> (SplitTag, SplitClause) -> TCMT IO (SplitTag, CoverResult))
-> (SplitClause -> TCM CoverResult)
-> (SplitTag, SplitClause)
-> TCMT IO (SplitTag, CoverResult)
forall a b. (a -> b) -> a -> b
$ QName -> [Clause] -> SplitClause -> TCM CoverResult
cover QName
f [Clause]
cs (SplitClause -> TCM CoverResult)
-> (SplitClause -> TCMT IO SplitClause)
-> SplitClause
-> TCM CoverResult
forall (m :: * -> *) b c a.
Monad m =>
(b -> m c) -> (a -> m b) -> a -> m c
<=< ((Telescope, SplitClause) -> SplitClause
forall a b. (a, b) -> b
snd ((Telescope, SplitClause) -> SplitClause)
-> (SplitClause -> TCM (Telescope, SplitClause))
-> SplitClause
-> TCMT IO SplitClause
forall (m :: * -> *) b c a.
Functor m =>
(b -> c) -> (a -> m b) -> a -> m c
<.> Bool -> SplitClause -> TCM (Telescope, SplitClause)
insertTrailingArgs Bool
False)) (((SplitTag, (SplitClause, IInfo)) -> (SplitTag, SplitClause))
-> [(SplitTag, (SplitClause, IInfo))] -> [(SplitTag, SplitClause)]
forall a b. (a -> b) -> [a] -> [b]
map (\(SplitTag
t,(SplitClause
sc,IInfo
i)) -> (SplitTag
t,SplitClause
sc)) [(SplitTag, (SplitClause, IInfo))]
scs)
            -- OR:
            -- forM scs $ \ (proj, sc') -> (proj,) <$> do
            --   cover f cs =<< do
            --     snd <$> fixTarget sc'
          let trees = (CoverResult -> SplitTree) -> [CoverResult] -> [SplitTree]
forall a b. (a -> b) -> [a] -> [b]
map CoverResult -> SplitTree
coverSplitTree [CoverResult]
results
              useds = (CoverResult -> IntSet) -> [CoverResult] -> [IntSet]
forall a b. (a -> b) -> [a] -> [b]
map CoverResult -> IntSet
coverUsedClauses [CoverResult]
results
              psss  = (CoverResult -> [(Telescope, NAPs)])
-> [CoverResult] -> [[(Telescope, NAPs)]]
forall a b. (a -> b) -> [a] -> [b]
map CoverResult -> [(Telescope, NAPs)]
coverMissingClauses [CoverResult]
results
              qsss  = (CoverResult -> [Clause]) -> [CoverResult] -> [[Clause]]
forall a b. (a -> b) -> [a] -> [b]
map CoverResult -> [Clause]
coverPatterns [CoverResult]
results
              noex  = (CoverResult -> IntSet) -> [CoverResult] -> [IntSet]
forall a b. (a -> b) -> [a] -> [b]
map CoverResult -> IntSet
coverNoExactClauses [CoverResult]
results
              tree  = Arg Int -> LazySplit -> [(SplitTag, SplitTree)] -> SplitTree
forall a. Arg Int -> LazySplit -> SplitTrees' a -> SplitTree' a
SplitAt Arg Int
n LazySplit
StrictSplit ([(SplitTag, SplitTree)] -> SplitTree)
-> [(SplitTag, SplitTree)] -> SplitTree
forall a b. (a -> b) -> a -> b
$ [SplitTag] -> [SplitTree] -> [(SplitTag, SplitTree)]
forall a b. [a] -> [b] -> [(a, b)]
zip [SplitTag]
projs [SplitTree]
trees   -- TODO: Lazy?
          return $ CoverResult tree (IntSet.unions useds) (concat psss) (concat qsss) (IntSet.unions noex)

    gatherEtaSplits :: Int -> SplitClause
                    -> [NamedArg SplitPattern] -> [NamedArg SplitPattern]
    gatherEtaSplits :: Int
-> SplitClause
-> [NamedArg SplitPattern]
-> [NamedArg SplitPattern]
gatherEtaSplits Int
n SplitClause
sc []
       | Int
n Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>= Int
0    = [NamedArg SplitPattern]
forall a. HasCallStack => a
__IMPOSSIBLE__ -- we should have encountered the main
                                    -- split by now already
       | Bool
otherwise = []
    gatherEtaSplits Int
n SplitClause
sc (NamedArg SplitPattern
p:[NamedArg SplitPattern]
ps) = case NamedArg SplitPattern -> SplitPattern
forall a. NamedArg a -> a
namedArg NamedArg SplitPattern
p of
      VarP PatternInfo
_ SplitPatVar
x
       | Int
n Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
0    -> case SplitPattern
p' of -- this is the main split
           VarP  PatternInfo
_ SplitPatVar
_    -> NamedArg SplitPattern
p NamedArg SplitPattern
-> [NamedArg SplitPattern] -> [NamedArg SplitPattern]
forall a. a -> [a] -> [a]
: Int
-> SplitClause
-> [NamedArg SplitPattern]
-> [NamedArg SplitPattern]
gatherEtaSplits (-Int
1) SplitClause
sc [NamedArg SplitPattern]
ps
           DotP  PatternInfo
_ Term
_    -> [NamedArg SplitPattern]
forall a. HasCallStack => a
__IMPOSSIBLE__
           ConP  ConHead
_ ConPatternInfo
_ [NamedArg SplitPattern]
qs -> [NamedArg SplitPattern]
qs [NamedArg SplitPattern]
-> [NamedArg SplitPattern] -> [NamedArg SplitPattern]
forall a. [a] -> [a] -> [a]
++ Int
-> SplitClause
-> [NamedArg SplitPattern]
-> [NamedArg SplitPattern]
gatherEtaSplits (-Int
1) SplitClause
sc [NamedArg SplitPattern]
ps
           LitP{}       -> Int
-> SplitClause
-> [NamedArg SplitPattern]
-> [NamedArg SplitPattern]
gatherEtaSplits (-Int
1) SplitClause
sc [NamedArg SplitPattern]
ps
           ProjP{}      -> [NamedArg SplitPattern]
forall a. HasCallStack => a
__IMPOSSIBLE__
           IApplyP{}    -> [NamedArg SplitPattern]
forall a. HasCallStack => a
__IMPOSSIBLE__
           DefP  PatternInfo
_ QName
_ [NamedArg SplitPattern]
qs -> [NamedArg SplitPattern]
qs [NamedArg SplitPattern]
-> [NamedArg SplitPattern] -> [NamedArg SplitPattern]
forall a. [a] -> [a] -> [a]
++ Int
-> SplitClause
-> [NamedArg SplitPattern]
-> [NamedArg SplitPattern]
gatherEtaSplits (-Int
1) SplitClause
sc [NamedArg SplitPattern]
ps -- __IMPOSSIBLE__ -- Andrea: maybe?
       | Bool
otherwise ->
           (SplitPattern -> SplitPattern)
-> NamedArg SplitPattern -> NamedArg SplitPattern
forall a b. (a -> b) -> NamedArg a -> NamedArg b
updateNamedArg (\ SplitPattern
_ -> SplitPattern
p') NamedArg SplitPattern
p NamedArg SplitPattern
-> [NamedArg SplitPattern] -> [NamedArg SplitPattern]
forall a. a -> [a] -> [a]
: Int
-> SplitClause
-> [NamedArg SplitPattern]
-> [NamedArg SplitPattern]
gatherEtaSplits (Int
nInt -> Int -> Int
forall a. Num a => a -> a -> a
-Int
1) SplitClause
sc [NamedArg SplitPattern]
ps
        where p' :: SplitPattern
p' = Substitution' SplitPattern -> Int -> SplitPattern
forall a. EndoSubst a => Substitution' a -> Int -> a
lookupS (SplitClause -> Substitution' SplitPattern
scSubst SplitClause
sc) (Int -> SplitPattern) -> Int -> SplitPattern
forall a b. (a -> b) -> a -> b
$ SplitPatVar -> Int
splitPatVarIndex SplitPatVar
x
      IApplyP{}   ->
           (SplitPattern -> SplitPattern)
-> NamedArg SplitPattern -> NamedArg SplitPattern
forall a b. (a -> b) -> NamedArg a -> NamedArg b
updateNamedArg (Substitution' (SubstArg SplitPattern)
-> SplitPattern -> SplitPattern
forall a. Subst a => Substitution' (SubstArg a) -> a -> a
applySubst (SplitClause -> Substitution' SplitPattern
scSubst SplitClause
sc)) NamedArg SplitPattern
p NamedArg SplitPattern
-> [NamedArg SplitPattern] -> [NamedArg SplitPattern]
forall a. a -> [a] -> [a]
: Int
-> SplitClause
-> [NamedArg SplitPattern]
-> [NamedArg SplitPattern]
gatherEtaSplits (Int
nInt -> Int -> Int
forall a. Num a => a -> a -> a
-Int
1) SplitClause
sc [NamedArg SplitPattern]
ps
      DotP  PatternInfo
_ Term
_    -> NamedArg SplitPattern
p NamedArg SplitPattern
-> [NamedArg SplitPattern] -> [NamedArg SplitPattern]
forall a. a -> [a] -> [a]
: Int
-> SplitClause
-> [NamedArg SplitPattern]
-> [NamedArg SplitPattern]
gatherEtaSplits (Int
nInt -> Int -> Int
forall a. Num a => a -> a -> a
-Int
1) SplitClause
sc [NamedArg SplitPattern]
ps -- count dot patterns
      ConP  ConHead
_ ConPatternInfo
_ [NamedArg SplitPattern]
qs -> Int
-> SplitClause
-> [NamedArg SplitPattern]
-> [NamedArg SplitPattern]
gatherEtaSplits Int
n SplitClause
sc ([NamedArg SplitPattern]
qs [NamedArg SplitPattern]
-> [NamedArg SplitPattern] -> [NamedArg SplitPattern]
forall a. [a] -> [a] -> [a]
++ [NamedArg SplitPattern]
ps)
      DefP  PatternInfo
_ QName
_ [NamedArg SplitPattern]
qs -> Int
-> SplitClause
-> [NamedArg SplitPattern]
-> [NamedArg SplitPattern]
gatherEtaSplits Int
n SplitClause
sc ([NamedArg SplitPattern]
qs [NamedArg SplitPattern]
-> [NamedArg SplitPattern] -> [NamedArg SplitPattern]
forall a. [a] -> [a] -> [a]
++ [NamedArg SplitPattern]
ps)
      LitP{}       -> Int
-> SplitClause
-> [NamedArg SplitPattern]
-> [NamedArg SplitPattern]
gatherEtaSplits Int
n SplitClause
sc [NamedArg SplitPattern]
ps
      ProjP{}      -> Int
-> SplitClause
-> [NamedArg SplitPattern]
-> [NamedArg SplitPattern]
gatherEtaSplits Int
n SplitClause
sc [NamedArg SplitPattern]
ps

    addEtaSplits :: Int -> [NamedArg SplitPattern] -> SplitTree -> SplitTree
    addEtaSplits :: Int -> [NamedArg SplitPattern] -> SplitTree -> SplitTree
addEtaSplits Int
k []     SplitTree
t = SplitTree
t
    addEtaSplits Int
k (NamedArg SplitPattern
p:[NamedArg SplitPattern]
ps) SplitTree
t = case NamedArg SplitPattern -> SplitPattern
forall a. NamedArg a -> a
namedArg NamedArg SplitPattern
p of
      VarP  PatternInfo
_ SplitPatVar
_     -> Int -> [NamedArg SplitPattern] -> SplitTree -> SplitTree
addEtaSplits (Int
k Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1) [NamedArg SplitPattern]
ps SplitTree
t
      DotP  PatternInfo
_ Term
_     -> Int -> [NamedArg SplitPattern] -> SplitTree -> SplitTree
addEtaSplits (Int
k Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1) [NamedArg SplitPattern]
ps SplitTree
t
      ConP ConHead
c ConPatternInfo
cpi [NamedArg SplitPattern]
qs -> Arg Int -> LazySplit -> [(SplitTag, SplitTree)] -> SplitTree
forall a. Arg Int -> LazySplit -> SplitTrees' a -> SplitTree' a
SplitAt (NamedArg SplitPattern
p NamedArg SplitPattern -> Int -> Arg Int
forall (f :: * -> *) a b. Functor f => f a -> b -> f b
$> Int
k) LazySplit
LazySplit [(QName -> SplitTag
SplitCon (ConHead -> QName
conName ConHead
c) , Int -> [NamedArg SplitPattern] -> SplitTree -> SplitTree
addEtaSplits Int
k ([NamedArg SplitPattern]
qs [NamedArg SplitPattern]
-> [NamedArg SplitPattern] -> [NamedArg SplitPattern]
forall a. [a] -> [a] -> [a]
++ [NamedArg SplitPattern]
ps) SplitTree
t)]
      LitP{}        -> SplitTree
forall a. HasCallStack => a
__IMPOSSIBLE__
      ProjP{}       -> SplitTree
forall a. HasCallStack => a
__IMPOSSIBLE__
      DefP{}        -> SplitTree
forall a. HasCallStack => a
__IMPOSSIBLE__ -- Andrea: maybe?
      IApplyP{}     -> Int -> [NamedArg SplitPattern] -> SplitTree -> SplitTree
addEtaSplits (Int
k Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1) [NamedArg SplitPattern]
ps SplitTree
t

    etaRecordSplits :: Int -> [NamedArg SplitPattern] -> (SplitTag,SplitClause)
                    -> SplitTree -> (SplitTag,SplitTree)
    etaRecordSplits :: Int
-> [NamedArg SplitPattern]
-> (SplitTag, SplitClause)
-> SplitTree
-> (SplitTag, SplitTree)
etaRecordSplits Int
n [NamedArg SplitPattern]
ps (SplitTag
q , SplitClause
sc) SplitTree
t =
      (SplitTag
q , Int -> [NamedArg SplitPattern] -> SplitTree -> SplitTree
addEtaSplits Int
0 (Int
-> SplitClause
-> [NamedArg SplitPattern]
-> [NamedArg SplitPattern]
gatherEtaSplits Int
n SplitClause
sc [NamedArg SplitPattern]
ps) SplitTree
t)


-- | Append a instance clause to the clauses of a function.
inferMissingClause
  :: QName
       -- ^ Function name.
  -> SplitClause
       -- ^ Clause to add.  Clause hiding (in 'clauseType') must be 'Instance'.
   -> TCM Clause
inferMissingClause :: QName -> SplitClause -> TCM Clause
inferMissingClause QName
f (SClause Telescope
tel [NamedArg SplitPattern]
ps Substitution' SplitPattern
_ Map CheckpointId (Substitution' Term)
cps (Just Dom Type
t)) = QName -> TCM Clause -> TCM Clause
forall (m :: * -> *) x a.
(MonadTrace m, HasRange x) =>
x -> m a -> m a
setCurrentRange QName
f (TCM Clause -> TCM Clause) -> TCM Clause -> TCM Clause
forall a b. (a -> b) -> a -> b
$ do
  [Char] -> Int -> TCMT IO Doc -> TCMT IO ()
forall (m :: * -> *).
MonadDebug m =>
[Char] -> Int -> TCMT IO Doc -> m ()
reportSDoc [Char]
"tc.cover.infer" Int
20 (TCMT IO Doc -> TCMT IO ()) -> TCMT IO Doc -> TCMT IO ()
forall a b. (a -> b) -> a -> b
$ Telescope -> TCMT IO Doc -> TCMT IO Doc
forall b (m :: * -> *) a.
(AddContext b, MonadAddContext m) =>
b -> m a -> m a
forall (m :: * -> *) a.
MonadAddContext m =>
Telescope -> m a -> m a
addContext Telescope
tel (TCMT IO Doc -> TCMT IO Doc) -> TCMT IO Doc -> TCMT IO Doc
forall a b. (a -> b) -> a -> b
$ TCMT IO Doc
"Trying to infer right-hand side of type" TCMT IO Doc -> TCMT IO Doc -> TCMT IO Doc
forall (m :: * -> *). Applicative m => m Doc -> m Doc -> m Doc
<+> Dom Type -> TCMT IO Doc
forall a (m :: * -> *). (PrettyTCM a, MonadPretty m) => a -> m Doc
forall (m :: * -> *). MonadPretty m => Dom Type -> m Doc
prettyTCM Dom Type
t
  rhs <-
    Telescope -> TCMT IO Term -> TCMT IO Term
forall b (m :: * -> *) a.
(AddContext b, MonadAddContext m) =>
b -> m a -> m a
forall (m :: * -> *) a.
MonadAddContext m =>
Telescope -> m a -> m a
addContext Telescope
tel
    (TCMT IO Term -> TCMT IO Term) -> TCMT IO Term -> TCMT IO Term
forall a b. (a -> b) -> a -> b
$ Lens' TCEnv (Map CheckpointId (Substitution' Term))
-> (Map CheckpointId (Substitution' Term)
    -> Map CheckpointId (Substitution' Term))
-> TCMT IO Term
-> TCMT IO Term
forall (m :: * -> *) a b.
MonadTCEnv m =>
Lens' TCEnv a -> (a -> a) -> m b -> m b
locallyTC (Map CheckpointId (Substitution' Term)
 -> f (Map CheckpointId (Substitution' Term)))
-> TCEnv -> f TCEnv
Lens' TCEnv (Map CheckpointId (Substitution' Term))
eCheckpoints (Map CheckpointId (Substitution' Term)
-> Map CheckpointId (Substitution' Term)
-> Map CheckpointId (Substitution' Term)
forall a b. a -> b -> a
const Map CheckpointId (Substitution' Term)
cps)
    (TCMT IO Term -> TCMT IO Term) -> TCMT IO Term -> TCMT IO Term
forall a b. (a -> b) -> a -> b
$ Substitution' Term -> TCMT IO Term -> TCMT IO Term
forall (tcm :: * -> *) a.
(MonadDebug tcm, MonadTCM tcm, MonadFresh CheckpointId tcm,
 ReadTCState tcm) =>
Substitution' Term -> tcm a -> tcm a
checkpoint Substitution' Term
forall a. Substitution' a
IdS    -- introduce a fresh checkpoint
    (TCMT IO Term -> TCMT IO Term) -> TCMT IO Term -> TCMT IO Term
forall a b. (a -> b) -> a -> b
$ case Dom Type -> Hiding
forall a. LensHiding a => a -> Hiding
getHiding Dom Type
t of
        Hiding
_ | Just Term
tac <- Dom Type -> Maybe Term
forall t e. Dom' t e -> Maybe t
domTactic Dom Type
t -> do
          [Char] -> Int -> TCMT IO Doc -> TCMT IO ()
forall (m :: * -> *).
MonadDebug m =>
[Char] -> Int -> TCMT IO Doc -> m ()
reportSDoc [Char]
"tc.cover.infer" Int
40 (TCMT IO Doc -> TCMT IO ()) -> TCMT IO Doc -> TCMT IO ()
forall a b. (a -> b) -> a -> b
$ [TCMT IO Doc] -> TCMT IO Doc
forall (m :: * -> *) (t :: * -> *).
(Applicative m, Foldable t) =>
t (m Doc) -> m Doc
vcat
            [ TCMT IO Doc
"@tactic rhs"
            , Int -> TCMT IO Doc -> TCMT IO Doc
forall (m :: * -> *). Functor m => Int -> m Doc -> m Doc
nest Int
2 (TCMT IO Doc -> TCMT IO Doc) -> TCMT IO Doc -> TCMT IO Doc
forall a b. (a -> b) -> a -> b
$ TCMT IO Doc
"target =" TCMT IO Doc -> TCMT IO Doc -> TCMT IO Doc
forall (m :: * -> *). Applicative m => m Doc -> m Doc -> m Doc
<+> Dom Type -> TCMT IO Doc
forall (m :: * -> *) a. (Applicative m, Pretty a) => a -> m Doc
pretty Dom Type
t ]
          (_, v) <- RunMetaOccursCheck -> Comparison -> Type -> TCMT IO (MetaId, Term)
forall (m :: * -> *).
MonadMetaSolver m =>
RunMetaOccursCheck -> Comparison -> Type -> m (MetaId, Term)
newValueMeta RunMetaOccursCheck
DontRunMetaOccursCheck Comparison
CmpLeq (Dom Type -> Type
forall t e. Dom' t e -> e
unDom Dom Type
t)
          v <$ unquoteTactic tac v (unDom t)
        Instance{} -> (MetaId, Term) -> Term
forall a b. (a, b) -> b
snd ((MetaId, Term) -> Term) -> TCMT IO (MetaId, Term) -> TCMT IO Term
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [Char] -> Type -> TCMT IO (MetaId, Term)
forall (m :: * -> *).
MonadMetaSolver m =>
[Char] -> Type -> m (MetaId, Term)
newInstanceMeta [Char]
"" (Dom Type -> Type
forall t e. Dom' t e -> e
unDom Dom Type
t)
        Hiding
Hidden     -> TCMT IO Term
forall a. HasCallStack => a
__IMPOSSIBLE__
        Hiding
NotHidden  -> TCMT IO Term
forall a. HasCallStack => a
__IMPOSSIBLE__
  let cl = Clause { clauseLHSRange :: Range
clauseLHSRange  = Range
forall a. Range' a
noRange
                  , clauseFullRange :: Range
clauseFullRange = Range
forall a. Range' a
noRange
                  , clauseTel :: Telescope
clauseTel       = Telescope
tel
                  , namedClausePats :: NAPs
namedClausePats = [NamedArg SplitPattern] -> NAPs
fromSplitPatterns [NamedArg SplitPattern]
ps
                  , clauseBody :: Maybe Term
clauseBody      = Term -> Maybe Term
forall a. a -> Maybe a
Just Term
rhs
                  , clauseType :: Maybe (Arg Type)
clauseType      = Arg Type -> Maybe (Arg Type)
forall a. a -> Maybe a
Just (Dom Type -> Arg Type
forall t a. Dom' t a -> Arg a
argFromDom Dom Type
t)
                  , clauseCatchall :: Bool
clauseCatchall    = Bool
False
                  , clauseExact :: Maybe Bool
clauseExact       = Bool -> Maybe Bool
forall a. a -> Maybe a
Just Bool
True
                  , clauseRecursive :: Maybe Bool
clauseRecursive   = Maybe Bool
forall a. Maybe a
Nothing     -- could be recursive
                  , clauseUnreachable :: Maybe Bool
clauseUnreachable = Bool -> Maybe Bool
forall a. a -> Maybe a
Just Bool
False  -- missing, thus, not unreachable
                  , clauseEllipsis :: ExpandedEllipsis
clauseEllipsis    = ExpandedEllipsis
NoEllipsis
                  , clauseWhereModule :: Maybe ModuleName
clauseWhereModule = Maybe ModuleName
forall a. Maybe a
Nothing
                  }
  addClauses f [cl]  -- Important: add at the end.
  return cl
inferMissingClause QName
_ (SClause Telescope
_ [NamedArg SplitPattern]
_ Substitution' SplitPattern
_ Map CheckpointId (Substitution' Term)
_ Maybe (Dom Type)
Nothing) = TCM Clause
forall a. HasCallStack => a
__IMPOSSIBLE__

splitStrategy :: BlockingVars -> Telescope -> TCM BlockingVars
splitStrategy :: BlockingVars -> Telescope -> TCM BlockingVars
splitStrategy BlockingVars
bs Telescope
tel = BlockingVars -> TCM BlockingVars
forall a. a -> TCMT IO a
forall (m :: * -> *) a. Monad m => a -> m a
return (BlockingVars -> TCM BlockingVars)
-> BlockingVars -> TCM BlockingVars
forall a b. (a -> b) -> a -> b
$ (BlockingVar -> BlockingVar) -> BlockingVars -> BlockingVars
forall a. (a -> a) -> [a] -> [a]
updateLast BlockingVar -> BlockingVar
setBlockingVarOverlap BlockingVars
xs
  -- Make sure we do not insists on precomputed coverage when
  -- we make our last try to split.
  -- Otherwise, we will not get a nice error message.
  where
    xs :: BlockingVars
xs             = BlockingVars
strict BlockingVars -> BlockingVars -> BlockingVars
forall a. [a] -> [a] -> [a]
++ BlockingVars
lazy
    (BlockingVars
lazy, BlockingVars
strict) = (BlockingVar -> Bool)
-> BlockingVars -> (BlockingVars, BlockingVars)
forall a. (a -> Bool) -> [a] -> ([a], [a])
List.partition BlockingVar -> Bool
blockingVarLazy BlockingVars
bs
{- KEEP!
--  Andreas, 2012-10-13
--  The following split strategy which prefers all-constructor columns
--  fails on test/fail/CoverStrategy
    xs       = ys ++ zs
    (ys, zs) = partition allConstructors bs
    allConstructors :: BlockingVar -> Bool
    allConstructors = isJust . snd
-}


-- | Check that a type is a non-irrelevant datatype or a record with
-- named constructor. Unless the 'Induction' argument is 'CoInductive'
-- the data type must be inductive.
isDatatype :: (MonadTCM tcm, MonadError SplitError tcm) =>
              Induction -> Dom Type ->
              tcm (DataOrRecord, QName, Args, Args, [QName], Bool)
isDatatype :: forall (tcm :: * -> *).
(MonadTCM tcm, MonadError SplitError tcm) =>
Induction
-> Dom Type -> tcm (DataOrRecord, QName, Args, Args, [QName], Bool)
isDatatype Induction
ind Dom Type
at = do
  let t :: Type
t       = Dom Type -> Type
forall t e. Dom' t e -> e
unDom Dom Type
at
      throw :: (Closure Type -> SplitError)
-> tcm (DataOrRecord, QName, Args, Args, [QName], Bool)
throw Closure Type -> SplitError
f = SplitError -> tcm (DataOrRecord, QName, Args, Args, [QName], Bool)
forall a. SplitError -> tcm a
forall e (m :: * -> *) a. MonadError e m => e -> m a
throwError (SplitError
 -> tcm (DataOrRecord, QName, Args, Args, [QName], Bool))
-> (Closure Type -> SplitError)
-> Closure Type
-> tcm (DataOrRecord, QName, Args, Args, [QName], Bool)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Closure Type -> SplitError
f (Closure Type
 -> tcm (DataOrRecord, QName, Args, Args, [QName], Bool))
-> tcm (Closure Type)
-> tcm (DataOrRecord, QName, Args, Args, [QName], Bool)
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< do TCM (Closure Type) -> tcm (Closure Type)
forall a. TCM a -> tcm a
forall (tcm :: * -> *) a. MonadTCM tcm => TCM a -> tcm a
liftTCM (TCM (Closure Type) -> tcm (Closure Type))
-> TCM (Closure Type) -> tcm (Closure Type)
forall a b. (a -> b) -> a -> b
$ Type -> TCM (Closure Type)
forall (m :: * -> *) a.
(MonadTCEnv m, ReadTCState m) =>
a -> m (Closure a)
buildClosure Type
t
  t' <- TCM Type -> tcm Type
forall a. TCM a -> tcm a
forall (tcm :: * -> *) a. MonadTCM tcm => TCM a -> tcm a
liftTCM (TCM Type -> tcm Type) -> TCM Type -> tcm Type
forall a b. (a -> b) -> a -> b
$ Type -> TCM Type
forall a (m :: * -> *). (Reduce a, MonadReduce m) => a -> m a
reduce Type
t
  mInterval <- liftTCM $ getBuiltinName' builtinInterval
  mIsOne <- liftTCM $ getBuiltinName' builtinIsOne
  case unEl t' of
    Def QName
d [] | QName -> Maybe QName
forall a. a -> Maybe a
Just QName
d Maybe QName -> Maybe QName -> Bool
forall a. Eq a => a -> a -> Bool
== Maybe QName
mInterval -> (Closure Type -> SplitError)
-> tcm (DataOrRecord, QName, Args, Args, [QName], Bool)
throw Closure Type -> SplitError
NotADatatype
    Def QName
d [Apply Arg Term
phi] | QName -> Maybe QName
forall a. a -> Maybe a
Just QName
d Maybe QName -> Maybe QName -> Bool
forall a. Eq a => a -> a -> Bool
== Maybe QName
mIsOne -> do
                xs <- TCM [(IntMap Bool, [Term])] -> tcm [(IntMap Bool, [Term])]
forall a. TCM a -> tcm a
forall (tcm :: * -> *) a. MonadTCM tcm => TCM a -> tcm a
liftTCM (TCM [(IntMap Bool, [Term])] -> tcm [(IntMap Bool, [Term])])
-> TCM [(IntMap Bool, [Term])] -> tcm [(IntMap Bool, [Term])]
forall a b. (a -> b) -> a -> b
$ Term -> TCM [(IntMap Bool, [Term])]
forall (m :: * -> *).
HasBuiltins m =>
Term -> m [(IntMap Bool, [Term])]
decomposeInterval (Term -> TCM [(IntMap Bool, [Term])])
-> TCMT IO Term -> TCM [(IntMap Bool, [Term])]
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< Term -> TCMT IO Term
forall a (m :: * -> *). (Reduce a, MonadReduce m) => a -> m a
reduce (Arg Term -> Term
forall e. Arg e -> e
unArg Arg Term
phi)
                if null xs
                   then return $ (IsData, d, [phi], [], [], False)
                   else throw NotADatatype
    Def QName
d Elims
es -> do
      let ~(Just Args
args) = Elims -> Maybe Args
forall a. [Elim' a] -> Maybe [Arg a]
allApplyElims Elims
es
      def <- TCM Defn -> tcm Defn
forall a. TCM a -> tcm a
forall (tcm :: * -> *) a. MonadTCM tcm => TCM a -> tcm a
liftTCM (TCM Defn -> tcm Defn) -> TCM Defn -> tcm Defn
forall a b. (a -> b) -> a -> b
$ Definition -> Defn
theDef (Definition -> Defn) -> TCMT IO Definition -> TCM Defn
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> QName -> TCMT IO Definition
forall (m :: * -> *). HasConstInfo m => QName -> m Definition
getConstInfo QName
d
      case def of
        Datatype{dataPars :: Defn -> Int
dataPars = Int
np, dataCons :: Defn -> [QName]
dataCons = [QName]
cs}
          | Bool
otherwise -> do
              let (Args
ps, Args
is) = Int -> Args -> (Args, Args)
forall a. Int -> [a] -> ([a], [a])
splitAt Int
np Args
args
              (DataOrRecord, QName, Args, Args, [QName], Bool)
-> tcm (DataOrRecord, QName, Args, Args, [QName], Bool)
forall a. a -> tcm a
forall (m :: * -> *) a. Monad m => a -> m a
return (DataOrRecord
forall p. DataOrRecord' p
IsData, QName
d, Args
ps, Args
is, [QName]
cs, Bool -> Bool
not (Bool -> Bool) -> Bool -> Bool
forall a b. (a -> b) -> a -> b
$ [QName] -> Bool
forall a. Null a => a -> Bool
null (Defn -> [QName]
dataPathCons Defn
def))
        Record{recPars :: Defn -> Int
recPars = Int
np, recConHead :: Defn -> ConHead
recConHead = ConHead
con, recInduction :: Defn -> Maybe Induction
recInduction = Maybe Induction
i, EtaEquality
recEtaEquality' :: EtaEquality
recEtaEquality' :: Defn -> EtaEquality
recEtaEquality'}
          | Maybe Induction
i Maybe Induction -> Maybe Induction -> Bool
forall a. Eq a => a -> a -> Bool
== Induction -> Maybe Induction
forall a. a -> Maybe a
Just Induction
CoInductive Bool -> Bool -> Bool
&& Induction
ind Induction -> Induction -> Bool
forall a. Eq a => a -> a -> Bool
/= Induction
CoInductive ->
              (Closure Type -> SplitError)
-> tcm (DataOrRecord, QName, Args, Args, [QName], Bool)
throw Closure Type -> SplitError
CoinductiveDatatype
          | Bool
otherwise ->
              (DataOrRecord, QName, Args, Args, [QName], Bool)
-> tcm (DataOrRecord, QName, Args, Args, [QName], Bool)
forall a. a -> tcm a
forall (m :: * -> *) a. Monad m => a -> m a
return (InductionAndEta -> DataOrRecord
forall p. p -> DataOrRecord' p
IsRecord InductionAndEta { recordInduction :: Maybe Induction
recordInduction=Maybe Induction
i, recordEtaEquality :: EtaEquality
recordEtaEquality=EtaEquality
recEtaEquality' }, QName
d, Args
args, [], [ConHead -> QName
conName ConHead
con], Bool
False)
        Defn
_ -> (Closure Type -> SplitError)
-> tcm (DataOrRecord, QName, Args, Args, [QName], Bool)
throw Closure Type -> SplitError
NotADatatype
    Term
_ -> (Closure Type -> SplitError)
-> tcm (DataOrRecord, QName, Args, Args, [QName], Bool)
throw Closure Type -> SplitError
NotADatatype

-- | Update the target type of the split clause after a case split.
fixTargetType
  :: Quantity  -- ^ The quantity of the thing that is split.
  -> SplitTag -> SplitClause -> Dom Type -> TCM SplitClause
fixTargetType :: Quantity
-> SplitTag -> SplitClause -> Dom Type -> TCMT IO SplitClause
fixTargetType Quantity
q SplitTag
tag sc :: SplitClause
sc@SClause{ scTel :: SplitClause -> Telescope
scTel = Telescope
sctel, scSubst :: SplitClause -> Substitution' SplitPattern
scSubst = Substitution' SplitPattern
sigma } Dom Type
target = do
    [Char] -> Int -> TCMT IO Doc -> TCMT IO ()
forall (m :: * -> *).
MonadDebug m =>
[Char] -> Int -> TCMT IO Doc -> m ()
reportSDoc [Char]
"tc.cover.target" Int
20 (TCMT IO Doc -> TCMT IO ()) -> TCMT IO Doc -> TCMT IO ()
forall a b. (a -> b) -> a -> b
$ [TCMT IO Doc] -> TCMT IO Doc
forall (m :: * -> *) (t :: * -> *).
(Applicative m, Foldable t) =>
t (m Doc) -> m Doc
sep
      [ TCMT IO Doc
"split clause telescope: " TCMT IO Doc -> TCMT IO Doc -> TCMT IO Doc
forall (m :: * -> *). Applicative m => m Doc -> m Doc -> m Doc
<+> Telescope -> TCMT IO Doc
forall a (m :: * -> *). (PrettyTCM a, MonadPretty m) => a -> m Doc
forall (m :: * -> *). MonadPretty m => Telescope -> m Doc
prettyTCM Telescope
sctel
      ]
    [Char] -> Int -> TCMT IO Doc -> TCMT IO ()
forall (m :: * -> *).
MonadDebug m =>
[Char] -> Int -> TCMT IO Doc -> m ()
reportSDoc [Char]
"tc.cover.target" Int
60 (TCMT IO Doc -> TCMT IO ()) -> TCMT IO Doc -> TCMT IO ()
forall a b. (a -> b) -> a -> b
$ [TCMT IO Doc] -> TCMT IO Doc
forall (m :: * -> *) (t :: * -> *).
(Applicative m, Foldable t) =>
t (m Doc) -> m Doc
sep
      [ TCMT IO Doc
"substitution          : " TCMT IO Doc -> TCMT IO Doc -> TCMT IO Doc
forall (m :: * -> *). Applicative m => m Doc -> m Doc -> m Doc
<+> Substitution' SplitPattern -> TCMT IO Doc
forall a (m :: * -> *). (PrettyTCM a, MonadPretty m) => a -> m Doc
forall (m :: * -> *).
MonadPretty m =>
Substitution' SplitPattern -> m Doc
prettyTCM Substitution' SplitPattern
sigma
      ]
    [Char] -> Int -> TCMT IO Doc -> TCMT IO ()
forall (m :: * -> *).
MonadDebug m =>
[Char] -> Int -> TCMT IO Doc -> m ()
reportSDoc [Char]
"tc.cover.target" Int
60 (TCMT IO Doc -> TCMT IO ()) -> TCMT IO Doc -> TCMT IO ()
forall a b. (a -> b) -> a -> b
$ [TCMT IO Doc] -> TCMT IO Doc
forall (m :: * -> *) (t :: * -> *).
(Applicative m, Foldable t) =>
t (m Doc) -> m Doc
sep
      [ TCMT IO Doc
"target type before substitution:" TCMT IO Doc -> TCMT IO Doc -> TCMT IO Doc
forall (m :: * -> *). Applicative m => m Doc -> m Doc -> m Doc
<+> Dom Type -> TCMT IO Doc
forall (m :: * -> *) a. (Applicative m, Pretty a) => a -> m Doc
pretty Dom Type
target
      , TCMT IO Doc
"             after substitution:" TCMT IO Doc -> TCMT IO Doc -> TCMT IO Doc
forall (m :: * -> *). Applicative m => m Doc -> m Doc -> m Doc
<+> Dom Type -> TCMT IO Doc
forall (m :: * -> *) a. (Applicative m, Pretty a) => a -> m Doc
pretty (Substitution' SplitPattern -> Dom Type -> Dom Type
forall a. TermSubst a => Substitution' SplitPattern -> a -> a
applySplitPSubst Substitution' SplitPattern
sigma Dom Type
target)
      ]

    -- We update the target quantity to 0 for erased constructors, but
    -- not if the match is made in an erased position, or if the
    -- original constructor definition is not erased.
    updQuant <- do
      let erased :: Bool
erased = case Quantity
q of
            Quantity0{} -> Bool
True
            Quantity1{} -> Bool
forall a. HasCallStack => a
__IMPOSSIBLE__
            Quantityω{} -> Bool
False
      if Bool
erased then (Dom Type -> Dom Type) -> TCMT IO (Dom Type -> Dom Type)
forall a. a -> TCMT IO a
forall (m :: * -> *) a. Monad m => a -> m a
return Dom Type -> Dom Type
forall a. a -> a
id else case SplitTag
tag of
        SplitCon QName
c -> do
          q <- Definition -> Quantity
forall a. LensQuantity a => a -> Quantity
getQuantity (Definition -> Quantity) -> TCMT IO Definition -> TCMT IO Quantity
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> QName -> TCMT IO Definition
forall (m :: * -> *).
(ReadTCState m, HasConstInfo m) =>
QName -> m Definition
getOriginalConstInfo QName
c
          case q of
            Quantity0{} -> (Dom Type -> Dom Type) -> TCMT IO (Dom Type -> Dom Type)
forall a. a -> TCMT IO a
forall (m :: * -> *) a. Monad m => a -> m a
return ((Dom Type -> Dom Type) -> TCMT IO (Dom Type -> Dom Type))
-> (Dom Type -> Dom Type) -> TCMT IO (Dom Type -> Dom Type)
forall a b. (a -> b) -> a -> b
$ (Quantity -> Quantity) -> Dom Type -> Dom Type
forall a. LensQuantity a => (Quantity -> Quantity) -> a -> a
mapQuantity (Quantity -> Quantity -> Quantity
composeQuantity Quantity
q)
            Quantity1{} -> (Dom Type -> Dom Type) -> TCMT IO (Dom Type -> Dom Type)
forall a. a -> TCMT IO a
forall (m :: * -> *) a. Monad m => a -> m a
return Dom Type -> Dom Type
forall a. a -> a
id
            Quantityω{} -> (Dom Type -> Dom Type) -> TCMT IO (Dom Type -> Dom Type)
forall a. a -> TCMT IO a
forall (m :: * -> *) a. Monad m => a -> m a
return Dom Type -> Dom Type
forall a. a -> a
id
        SplitLit{} -> (Dom Type -> Dom Type) -> TCMT IO (Dom Type -> Dom Type)
forall a. a -> TCMT IO a
forall (m :: * -> *) a. Monad m => a -> m a
return Dom Type -> Dom Type
forall a. a -> a
id
        SplitCatchall{} -> (Dom Type -> Dom Type) -> TCMT IO (Dom Type -> Dom Type)
forall a. a -> TCMT IO a
forall (m :: * -> *) a. Monad m => a -> m a
return Dom Type -> Dom Type
forall a. a -> a
id

    return $ sc { scTarget = Just $ updQuant $ applySplitPSubst sigma target }


-- | Add more patterns to split clause if the target type is a function type.
--   Returns the domains of the function type (if any).
insertTrailingArgs
  :: Bool         -- ^ Force insertion even when there is a 'domTactic'?
  -> SplitClause
  -> TCM (Telescope, SplitClause)
insertTrailingArgs :: Bool -> SplitClause -> TCM (Telescope, SplitClause)
insertTrailingArgs Bool
force sc :: SplitClause
sc@SClause{ scTel :: SplitClause -> Telescope
scTel = Telescope
sctel, scPats :: SplitClause -> [NamedArg SplitPattern]
scPats = [NamedArg SplitPattern]
ps, scSubst :: SplitClause -> Substitution' SplitPattern
scSubst = Substitution' SplitPattern
sigma, scCheckpoints :: SplitClause -> Map CheckpointId (Substitution' Term)
scCheckpoints = Map CheckpointId (Substitution' Term)
cps, scTarget :: SplitClause -> Maybe (Dom Type)
scTarget = Maybe (Dom Type)
target } = do
  let fallback :: TCM (Telescope, SplitClause)
fallback = (Telescope, SplitClause) -> TCM (Telescope, SplitClause)
forall a. a -> TCMT IO a
forall (m :: * -> *) a. Monad m => a -> m a
return (Telescope
forall a. Null a => a
empty, SplitClause
sc)
  Maybe (Dom Type)
-> TCM (Telescope, SplitClause)
-> (Dom Type -> TCM (Telescope, SplitClause))
-> TCM (Telescope, SplitClause)
forall a b. Maybe a -> b -> (a -> b) -> b
caseMaybe Maybe (Dom Type)
target TCM (Telescope, SplitClause)
fallback ((Dom Type -> TCM (Telescope, SplitClause))
 -> TCM (Telescope, SplitClause))
-> (Dom Type -> TCM (Telescope, SplitClause))
-> TCM (Telescope, SplitClause)
forall a b. (a -> b) -> a -> b
$ \ Dom Type
a -> do
    if Maybe Term -> Bool
forall a. Maybe a -> Bool
isJust (Dom Type -> Maybe Term
forall t e. Dom' t e -> Maybe t
domTactic Dom Type
a) Bool -> Bool -> Bool
&& Bool -> Bool
not Bool
force then TCM (Telescope, SplitClause)
fallback else do
    (TelV tel b) <- Telescope -> TCMT IO (TelV Type) -> TCMT IO (TelV Type)
forall b (m :: * -> *) a.
(AddContext b, MonadAddContext m) =>
b -> m a -> m a
forall (m :: * -> *) a.
MonadAddContext m =>
Telescope -> m a -> m a
addContext Telescope
sctel (TCMT IO (TelV Type) -> TCMT IO (TelV Type))
-> TCMT IO (TelV Type) -> TCMT IO (TelV Type)
forall a b. (a -> b) -> a -> b
$ Int -> Type -> TCMT IO (TelV Type)
forall (m :: * -> *).
(MonadReduce m, MonadAddContext m) =>
Int -> Type -> m (TelV Type)
telViewUpTo (-Int
1) (Type -> TCMT IO (TelV Type)) -> Type -> TCMT IO (TelV Type)
forall a b. (a -> b) -> a -> b
$ Dom Type -> Type
forall t e. Dom' t e -> e
unDom Dom Type
a
    reportSDoc "tc.cover.target" 15 $ sep
      [ "target type telescope: " <+> do
          addContext sctel $ prettyTCM tel
      , "target type core     : " <+> do
          addContext sctel $ addContext tel $ prettyTCM b
      ]
    let n         = Telescope -> Int
forall a. Sized a => a -> Int
size Telescope
tel
        -- Andreas, 2016-10-04 issue #2236
        -- Need to set origin to "Inserted" to avoid printing of hidden patterns.
        xs        = (NamedArg SplitPattern -> NamedArg SplitPattern)
-> [NamedArg SplitPattern] -> [NamedArg SplitPattern]
forall a b. (a -> b) -> [a] -> [b]
map ((ArgInfo -> ArgInfo)
-> NamedArg SplitPattern -> NamedArg SplitPattern
forall a. LensArgInfo a => (ArgInfo -> ArgInfo) -> a -> a
mapArgInfo ArgInfo -> ArgInfo
hiddenInserted) ([NamedArg SplitPattern] -> [NamedArg SplitPattern])
-> [NamedArg SplitPattern] -> [NamedArg SplitPattern]
forall a b. (a -> b) -> a -> b
$ Telescope -> [NamedArg SplitPattern]
forall a t. DeBruijn a => Tele (Dom t) -> [NamedArg a]
teleNamedArgs Telescope
tel
        -- Compute new split clause
        sctel'    = ListTel -> Telescope
telFromList (ListTel -> Telescope) -> ListTel -> Telescope
forall a b. (a -> b) -> a -> b
$ Telescope -> ListTel
forall t. Tele (Dom t) -> [Dom ([Char], t)]
telToList (Int -> Telescope -> Telescope
forall a. Subst a => Int -> a -> a
raise Int
n Telescope
sctel) ListTel -> ListTel -> ListTel
forall a. [a] -> [a] -> [a]
++ Telescope -> ListTel
forall t. Tele (Dom t) -> [Dom ([Char], t)]
telToList Telescope
tel
        -- Dot patterns in @ps@ need to be raised!  (Issue 1298)
        ps'       = Substitution' (SubstArg [NamedArg SplitPattern])
-> [NamedArg SplitPattern] -> [NamedArg SplitPattern]
forall a. Subst a => Substitution' (SubstArg a) -> a -> a
applySubst (Int -> Substitution' SplitPattern
forall a. Int -> Substitution' a
raiseS Int
n) [NamedArg SplitPattern]
ps [NamedArg SplitPattern]
-> [NamedArg SplitPattern] -> [NamedArg SplitPattern]
forall a. [a] -> [a] -> [a]
++ [NamedArg SplitPattern]
xs
        newTarget = Dom Type -> Maybe (Dom Type)
forall a. a -> Maybe a
Just (Dom Type -> Maybe (Dom Type)) -> Dom Type -> Maybe (Dom Type)
forall a b. (a -> b) -> a -> b
$ (if Bool -> Bool
not (Telescope -> Bool
forall a. Null a => a -> Bool
null Telescope
tel) then Dom Type
a{ domTactic = Nothing } else Dom Type
a) Dom Type -> Type -> Dom Type
forall (f :: * -> *) a b. Functor f => f a -> b -> f b
$> Type
b
        sc'       = SClause
          { scTel :: Telescope
scTel    = Telescope
sctel'
          , scPats :: [NamedArg SplitPattern]
scPats   = [NamedArg SplitPattern]
ps'
          , scSubst :: Substitution' SplitPattern
scSubst  = Int -> Substitution' SplitPattern -> Substitution' SplitPattern
forall a. Int -> Substitution' a -> Substitution' a
wkS Int
n (Substitution' SplitPattern -> Substitution' SplitPattern)
-> Substitution' SplitPattern -> Substitution' SplitPattern
forall a b. (a -> b) -> a -> b
$ Substitution' SplitPattern
sigma -- Should be wkS instead of liftS since
                                     -- variables are only added to new tel.
          , scCheckpoints :: Map CheckpointId (Substitution' Term)
scCheckpoints        = Substitution' (SubstArg (Map CheckpointId (Substitution' Term)))
-> Map CheckpointId (Substitution' Term)
-> Map CheckpointId (Substitution' Term)
forall a. Subst a => Substitution' (SubstArg a) -> a -> a
applySubst (Int -> Substitution' Term
forall a. Int -> Substitution' a
raiseS Int
n) Map CheckpointId (Substitution' Term)
cps
          , scTarget :: Maybe (Dom Type)
scTarget = Maybe (Dom Type)
newTarget
          }
    -- Separate debug printing to find cause of crash (Issue 1374)
    reportSDoc "tc.cover.target" 30 $ sep
      [ "new split clause telescope   : " <+> prettyTCM sctel'
      ]
    reportSDoc "tc.cover.target" 30 $ sep
      [ "new split clause patterns    : " <+> do
          addContext sctel' $ prettyTCMPatternList $ fromSplitPatterns ps'
      ]
    reportSDoc "tc.cover.target" 60 $ sep
      [ "new split clause substitution: " <+> prettyTCM (scSubst sc')
      ]
    reportSDoc "tc.cover.target" 30 $ sep
      [ "new split clause target      : " <+> do
          addContext sctel' $ prettyTCM $ fromJust newTarget
      ]
    reportSDoc "tc.cover.target" 20 $ sep
      [ "new split clause"
      , prettyTCM sc'
      ]
    return $ if n == 0 then (empty, sc { scTarget = newTarget }) else (tel, sc')

-- Andreas, 2017-01-18, issue #819, set visible arguments to UserWritten.
-- Otherwise, they will be printed as _.
hiddenInserted :: ArgInfo -> ArgInfo
hiddenInserted :: ArgInfo -> ArgInfo
hiddenInserted ArgInfo
ai
  | ArgInfo -> Bool
forall a. LensHiding a => a -> Bool
visible ArgInfo
ai = Origin -> ArgInfo -> ArgInfo
forall a. LensOrigin a => Origin -> a -> a
setOrigin Origin
UserWritten ArgInfo
ai
  | Bool
otherwise  = Origin -> ArgInfo -> ArgInfo
forall a. LensOrigin a => Origin -> a -> a
setOrigin Origin
Inserted ArgInfo
ai


-- | Checks if a type in this sort supports hcomp.
--   currently all such types will have a Level.
--   precondition: Sort in whnf and not blocked.
hasHComp :: Sort -> Maybe Level
hasHComp :: Sort -> Maybe Level
hasHComp (Type Level
l) = Level -> Maybe Level
forall a. a -> Maybe a
Just Level
l
hasHComp Sort
_        = Maybe Level
forall a. Maybe a
Nothing


computeHCompSplit  :: Telescope   -- ^ Telescope before split point.
  -> PatVarName                   -- ^ Name of pattern variable at split point.
  -> Telescope                    -- ^ Telescope after split point.
  -> QName                        -- ^ Name of datatype to split at.
  -> Args                         -- ^ Data type parameters.
  -> Args                         -- ^ Data type indices.
  -> Nat                          -- ^ Index of split variable.
  -> Telescope                    -- ^ Telescope for the patterns.
  -> [NamedArg SplitPattern]      -- ^ Patterns before doing the split.
  -> Map CheckpointId Substitution -- ^ Current checkpoints
  -- -> QName                        -- ^ Constructor to fit into hole.
  -> CoverM (Maybe (SplitTag,SplitClause))   -- ^ New split clause if successful.
computeHCompSplit :: Telescope
-> [Char]
-> Telescope
-> QName
-> Args
-> Args
-> Int
-> Telescope
-> [NamedArg SplitPattern]
-> Map CheckpointId (Substitution' Term)
-> CoverM (Maybe (SplitTag, SplitClause))
computeHCompSplit Telescope
delta1 [Char]
n Telescope
delta2 QName
d Args
pars Args
ixs Int
hix Telescope
tel [NamedArg SplitPattern]
ps Map CheckpointId (Substitution' Term)
cps = do
  withK   <- Bool -> Bool
not (Bool -> Bool)
-> ExceptT SplitError (TCMT IO) Bool
-> ExceptT SplitError (TCMT IO) Bool
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ExceptT SplitError (TCMT IO) Bool
forall (m :: * -> *). HasOptions m => m Bool
cubicalCompatibleOption
  if withK then return Nothing else do
    -- Get the type of the datatype
  -- Δ1 ⊢ dtype
  dsort <- liftTCM $ (parallelS (reverse $ map unArg pars) `applySubst`) . dataSort . theDef <$> getConstInfo d
  hCompName <- fromMaybe __IMPOSSIBLE__ <$> getPrimitiveName' builtinHComp
  theHCompT <- defType <$> getConstInfo hCompName

  -- TODO can dsort be blocked or not in whnf?
  caseMaybe (hasHComp dsort) (return Nothing) $ \ Level
dlvl' -> do
  let
    dlvl :: Term
dlvl = Level -> Term
Level Level
dlvl'
    dterm :: Term
dterm = QName -> Elims -> Term
Def QName
d [] Term -> Args -> Term
forall t. Apply t => t -> Args -> t
`apply` (Args
pars Args -> Args -> Args
forall a. [a] -> [a] -> [a]
++ Args
ixs)
  -- Δ1 ⊢ gamma
  TelV gamma _ <- TCMT IO (TelV Type) -> ExceptT SplitError (TCMT IO) (TelV Type)
forall (m :: * -> *) a. Monad m => m a -> ExceptT SplitError m a
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (TCMT IO (TelV Type) -> ExceptT SplitError (TCMT IO) (TelV Type))
-> TCMT IO (TelV Type) -> ExceptT SplitError (TCMT IO) (TelV Type)
forall a b. (a -> b) -> a -> b
$ Type -> TCMT IO (TelV Type)
forall (m :: * -> *).
(MonadReduce m, MonadAddContext m) =>
Type -> m (TelV Type)
telView (Type
theHCompT Type -> Args -> Type
`piApply` [Hiding -> Arg Term -> Arg Term
forall a. LensHiding a => Hiding -> a -> a
setHiding Hiding
Hidden (Arg Term -> Arg Term) -> Arg Term -> Arg Term
forall a b. (a -> b) -> a -> b
$ Term -> Arg Term
forall a. a -> Arg a
defaultArg (Term -> Arg Term) -> Term -> Arg Term
forall a b. (a -> b) -> a -> b
$ Term
dlvl , Term -> Arg Term
forall a. a -> Arg a
defaultArg (Term -> Arg Term) -> Term -> Arg Term
forall a b. (a -> b) -> a -> b
$ Term
dterm])
  case (delta1 `abstract` gamma,IdS) of
    (Telescope
delta1',PatternSubstitution
rho0) -> do
--      debugSubst "rho0" rho0

      -- We have Δ₁' ⊢ ρ₀ : Δ₁Γ, so split it into the part for Δ₁ and the part for Γ
      let (Substitution' SplitPattern
rho1,Substitution' SplitPattern
rho2) = Int
-> Substitution' SplitPattern
-> (Substitution' SplitPattern, Substitution' SplitPattern)
forall a.
Int -> Substitution' a -> (Substitution' a, Substitution' a)
splitS (Telescope -> Int
forall a. Sized a => a -> Int
size Telescope
gamma) (Substitution' SplitPattern
 -> (Substitution' SplitPattern, Substitution' SplitPattern))
-> Substitution' SplitPattern
-> (Substitution' SplitPattern, Substitution' SplitPattern)
forall a b. (a -> b) -> a -> b
$ PatternSubstitution -> Substitution' SplitPattern
toSplitPSubst PatternSubstitution
rho0

      let defp :: SplitPattern
defp = PatternInfo -> QName -> [NamedArg SplitPattern] -> SplitPattern
forall x.
PatternInfo -> QName -> [NamedArg (Pattern' x)] -> Pattern' x
DefP PatternInfo
defaultPatternInfo QName
hCompName ([NamedArg SplitPattern] -> SplitPattern)
-> ([NamedArg SplitPattern] -> [NamedArg SplitPattern])
-> [NamedArg SplitPattern]
-> SplitPattern
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (NamedArg SplitPattern -> NamedArg SplitPattern)
-> [NamedArg SplitPattern] -> [NamedArg SplitPattern]
forall a b. (a -> b) -> [a] -> [b]
map (Origin -> NamedArg SplitPattern -> NamedArg SplitPattern
forall a. LensOrigin a => Origin -> a -> a
setOrigin Origin
Inserted) ([NamedArg SplitPattern] -> SplitPattern)
-> [NamedArg SplitPattern] -> SplitPattern
forall a b. (a -> b) -> a -> b
$ -- should there be a different Origin here?
                   (Arg SplitPattern -> NamedArg SplitPattern)
-> [Arg SplitPattern] -> [NamedArg SplitPattern]
forall a b. (a -> b) -> [a] -> [b]
map ((SplitPattern -> Named NamedName SplitPattern)
-> Arg SplitPattern -> NamedArg SplitPattern
forall a b. (a -> b) -> Arg a -> Arg b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap SplitPattern -> Named NamedName SplitPattern
forall a name. a -> Named name a
unnamed) [Hiding -> Arg SplitPattern -> Arg SplitPattern
forall a. LensHiding a => Hiding -> a -> a
setHiding Hiding
Hidden (Arg SplitPattern -> Arg SplitPattern)
-> Arg SplitPattern -> Arg SplitPattern
forall a b. (a -> b) -> a -> b
$ SplitPattern -> Arg SplitPattern
forall a. a -> Arg a
defaultArg (SplitPattern -> Arg SplitPattern)
-> SplitPattern -> Arg SplitPattern
forall a b. (a -> b) -> a -> b
$ Substitution' (SubstArg SplitPattern)
-> SplitPattern -> SplitPattern
forall a. Subst a => Substitution' (SubstArg a) -> a -> a
applySubst Substitution' SplitPattern
Substitution' (SubstArg SplitPattern)
rho1 (SplitPattern -> SplitPattern) -> SplitPattern -> SplitPattern
forall a b. (a -> b) -> a -> b
$ PatternInfo -> Term -> SplitPattern
forall x. PatternInfo -> Term -> Pattern' x
DotP PatternInfo
defaultPatternInfo (Term -> SplitPattern) -> Term -> SplitPattern
forall a b. (a -> b) -> a -> b
$ Term
dlvl
                                      ,Hiding -> Arg SplitPattern -> Arg SplitPattern
forall a. LensHiding a => Hiding -> a -> a
setHiding Hiding
Hidden (Arg SplitPattern -> Arg SplitPattern)
-> Arg SplitPattern -> Arg SplitPattern
forall a b. (a -> b) -> a -> b
$ SplitPattern -> Arg SplitPattern
forall a. a -> Arg a
defaultArg (SplitPattern -> Arg SplitPattern)
-> SplitPattern -> Arg SplitPattern
forall a b. (a -> b) -> a -> b
$ Substitution' (SubstArg SplitPattern)
-> SplitPattern -> SplitPattern
forall a. Subst a => Substitution' (SubstArg a) -> a -> a
applySubst Substitution' SplitPattern
Substitution' (SubstArg SplitPattern)
rho1 (SplitPattern -> SplitPattern) -> SplitPattern -> SplitPattern
forall a b. (a -> b) -> a -> b
$ PatternInfo -> Term -> SplitPattern
forall x. PatternInfo -> Term -> Pattern' x
DotP PatternInfo
defaultPatternInfo (Term -> SplitPattern) -> Term -> SplitPattern
forall a b. (a -> b) -> a -> b
$ Term
dterm]
                   [NamedArg SplitPattern]
-> [NamedArg SplitPattern] -> [NamedArg SplitPattern]
forall a. [a] -> [a] -> [a]
++ Substitution' (SubstArg [NamedArg SplitPattern])
-> [NamedArg SplitPattern] -> [NamedArg SplitPattern]
forall a. Subst a => Substitution' (SubstArg a) -> a -> a
applySubst Substitution' SplitPattern
Substitution' (SubstArg [NamedArg SplitPattern])
rho2 (Telescope -> [NamedArg SplitPattern]
forall a t. DeBruijn a => Tele (Dom t) -> [NamedArg a]
teleNamedArgs Telescope
gamma) -- rho0?
      -- Compute final context and substitution
      let rho3 :: Substitution' SplitPattern
rho3    = SplitPattern
-> Substitution' SplitPattern -> Substitution' SplitPattern
forall a. DeBruijn a => a -> Substitution' a -> Substitution' a
consS SplitPattern
defp Substitution' SplitPattern
rho1            -- Δ₁' ⊢ ρ₃ : Δ₁(x:D)
          delta2' :: Telescope
delta2' = Substitution' SplitPattern -> Telescope -> Telescope
forall a. TermSubst a => Substitution' SplitPattern -> a -> a
applySplitPSubst Substitution' SplitPattern
rho3 Telescope
delta2  -- Δ₂' = Δ₂ρ₃
          delta' :: Telescope
delta'  = Telescope
delta1' Telescope -> Telescope -> Telescope
forall t. Abstract t => Telescope -> t -> t
`abstract` Telescope
delta2' -- Δ'  = Δ₁'Δ₂'
          rho :: Substitution' SplitPattern
rho     = Int -> Substitution' SplitPattern -> Substitution' SplitPattern
forall a. Int -> Substitution' a -> Substitution' a
liftS (Telescope -> Int
forall a. Sized a => a -> Int
size Telescope
delta2) Substitution' SplitPattern
rho3   -- Δ' ⊢ ρ : Δ₁(x:D)Δ₂

      -- debugTel "delta'" delta'
      -- debugSubst "rho" rho
      -- debugPs tel ps

      -- Apply the substitution
      let ps' :: [NamedArg SplitPattern]
ps' = Substitution' (SubstArg [NamedArg SplitPattern])
-> [NamedArg SplitPattern] -> [NamedArg SplitPattern]
forall a. Subst a => Substitution' (SubstArg a) -> a -> a
applySubst Substitution' SplitPattern
Substitution' (SubstArg [NamedArg SplitPattern])
rho [NamedArg SplitPattern]
ps
      -- debugPlugged delta' ps'

      let cps' :: Map CheckpointId (Substitution' Term)
cps' = Substitution' SplitPattern
-> Map CheckpointId (Substitution' Term)
-> Map CheckpointId (Substitution' Term)
forall a. TermSubst a => Substitution' SplitPattern -> a -> a
applySplitPSubst Substitution' SplitPattern
rho Map CheckpointId (Substitution' Term)
cps

      Maybe (SplitTag, SplitClause)
-> CoverM (Maybe (SplitTag, SplitClause))
forall a. a -> ExceptT SplitError (TCMT IO) a
forall (m :: * -> *) a. Monad m => a -> m a
return (Maybe (SplitTag, SplitClause)
 -> CoverM (Maybe (SplitTag, SplitClause)))
-> Maybe (SplitTag, SplitClause)
-> CoverM (Maybe (SplitTag, SplitClause))
forall a b. (a -> b) -> a -> b
$ (SplitTag, SplitClause) -> Maybe (SplitTag, SplitClause)
forall a. a -> Maybe a
Just ((SplitTag, SplitClause) -> Maybe (SplitTag, SplitClause))
-> (SplitClause -> (SplitTag, SplitClause))
-> SplitClause
-> Maybe (SplitTag, SplitClause)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (QName -> SplitTag
SplitCon QName
hCompName,) (SplitClause -> Maybe (SplitTag, SplitClause))
-> SplitClause -> Maybe (SplitTag, SplitClause)
forall a b. (a -> b) -> a -> b
$ Telescope
-> [NamedArg SplitPattern]
-> Substitution' SplitPattern
-> Map CheckpointId (Substitution' Term)
-> Maybe (Dom Type)
-> SplitClause
SClause Telescope
delta' [NamedArg SplitPattern]
ps' Substitution' SplitPattern
rho Map CheckpointId (Substitution' Term)
cps' Maybe (Dom Type)
forall a. Maybe a
Nothing -- target fixed later


-- | @computeNeighbourhood delta1 delta2 d pars ixs hix tel ps con@
--
--   @
--      delta1   Telescope before split point
--      n        Name of pattern variable at split point
--      delta2   Telescope after split point
--      d        Name of datatype to split at
--      pars     Data type parameters
--      ixs      Data type indices
--      hix      Index of split variable
--      tel      Telescope for patterns ps
--      ps       Patterns before doing the split
--      cps      Current module parameter checkpoints
--      con      Constructor to fit into hole
--   @
--   @dtype == d pars ixs@
computeNeighbourhood
  :: Telescope                    -- ^ Telescope before split point.
  -> PatVarName                   -- ^ Name of pattern variable at split point.
  -> Telescope                    -- ^ Telescope after split point.
  -> QName                        -- ^ Name of datatype to split at.
  -> Args                         -- ^ Data type parameters.
  -> Args                         -- ^ Data type indices.
  -> Nat                          -- ^ Index of split variable.
  -> Telescope                    -- ^ Telescope for the patterns.
  -> [NamedArg SplitPattern]      -- ^ Patterns before doing the split.
  -> Map CheckpointId Substitution -- ^ Current checkpoints
  -> QName                        -- ^ Constructor to fit into hole.
  -> CoverM (Maybe (SplitClause, IInfo))   -- ^ New split clause if successful.
computeNeighbourhood :: Telescope
-> [Char]
-> Telescope
-> QName
-> Args
-> Args
-> Int
-> Telescope
-> [NamedArg SplitPattern]
-> Map CheckpointId (Substitution' Term)
-> QName
-> CoverM (Maybe (SplitClause, IInfo))
computeNeighbourhood Telescope
delta1 [Char]
n Telescope
delta2 QName
d Args
pars Args
ixs Int
hix Telescope
tel [NamedArg SplitPattern]
ps Map CheckpointId (Substitution' Term)
cps QName
c = do

  -- Get the type of the datatype
  dtype <- TCM Type -> ExceptT SplitError (TCMT IO) Type
forall a. TCM a -> ExceptT SplitError (TCMT IO) a
forall (tcm :: * -> *) a. MonadTCM tcm => TCM a -> tcm a
liftTCM (TCM Type -> ExceptT SplitError (TCMT IO) Type)
-> TCM Type -> ExceptT SplitError (TCMT IO) Type
forall a b. (a -> b) -> a -> b
$ (Type -> Args -> Type
`piApply` Args
pars) (Type -> Type) -> (Definition -> Type) -> Definition -> Type
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Definition -> Type
defType (Definition -> Type) -> TCMT IO Definition -> TCM Type
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> QName -> TCMT IO Definition
forall (m :: * -> *). HasConstInfo m => QName -> m Definition
getConstInfo QName
d

  -- Get the real constructor name
  con <- liftTCM $ fromRight __IMPOSSIBLE__ <$> getConForm c
  con <- return $ con { conName = c }  -- What if we restore the current name?
                                       -- Andreas, 2013-11-29 changes nothing!

  -- Get the type of the constructor
  ctype <- liftTCM $ defType <$> getConInfo con

  -- Lookup the type of the constructor at the given parameters
  (gamma0, cixs, boundary) <- do
    (TelV gamma0 (El _ d), boundary) <- liftTCM $ addContext delta1 $
      telViewPathBoundaryP (ctype `piApply` pars)
    let Def _ es = d
        Just cixs = allApplyElims es
    return (gamma0, cixs, boundary)

  let (_, Dom{domInfo = info} : _) = splitAt (size tel - hix - 1) (telToList tel)

  -- Andreas, 2012-02-25 preserve name suggestion for recursive arguments
  -- of constructor

  let preserve ([Char]
x, t :: Type
t@(El Sort
_ (Def QName
d' Elims
_))) | QName
d QName -> QName -> Bool
forall a. Eq a => a -> a -> Bool
== QName
d' = ([Char]
n, Type
t)
      preserve ([Char]
x, Type
t) = ([Char]
x, Type
t)
      gamma  = ((Dom Type -> Dom Type) -> Telescope -> Telescope
forall a b. (a -> b) -> Tele a -> Tele b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ((Dom Type -> Dom Type) -> Telescope -> Telescope)
-> ((Modality -> Modality) -> Dom Type -> Dom Type)
-> (Modality -> Modality)
-> Telescope
-> Telescope
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Modality -> Modality) -> Dom Type -> Dom Type
forall a. LensModality a => (Modality -> Modality) -> a -> a
mapModality) (Modality -> Modality -> Modality
composeModality (ArgInfo -> Modality
forall a. LensModality a => a -> Modality
getModality ArgInfo
info)) (Telescope -> Telescope) -> Telescope -> Telescope
forall a b. (a -> b) -> a -> b
$ ListTel -> Telescope
telFromList (ListTel -> Telescope)
-> (Telescope -> ListTel) -> Telescope -> Telescope
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Dom ([Char], Type) -> Dom ([Char], Type)) -> ListTel -> ListTel
forall a b. (a -> b) -> [a] -> [b]
map ((([Char], Type) -> ([Char], Type))
-> Dom ([Char], Type) -> Dom ([Char], Type)
forall a b. (a -> b) -> Dom' Term a -> Dom' Term b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ([Char], Type) -> ([Char], Type)
preserve) (ListTel -> ListTel)
-> (Telescope -> ListTel) -> Telescope -> ListTel
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Telescope -> ListTel
forall t. Tele (Dom t) -> [Dom ([Char], t)]
telToList (Telescope -> Telescope) -> Telescope -> Telescope
forall a b. (a -> b) -> a -> b
$ Telescope
gamma0
      delta1Gamma = Telescope
delta1 Telescope -> Telescope -> Telescope
forall t. Abstract t => Telescope -> t -> t
`abstract` Telescope
gamma

  debugInit con ctype d pars ixs cixs delta1 delta2 gamma tel ps hix

  cforced <- defForced <$> getConstInfo c
      -- Variables in Δ₁ are not forced, since the unifier takes care to not introduce forced
      -- variables.
  let forced = Int -> IsForced -> [IsForced]
forall a. Int -> a -> [a]
replicate (Telescope -> Int
forall a. Sized a => a -> Int
size Telescope
delta1) IsForced
NotForced [IsForced] -> [IsForced] -> [IsForced]
forall a. [a] -> [a] -> [a]
++ [IsForced]
cforced
      flex   = [IsForced] -> Telescope -> FlexibleVars
allFlexVars [IsForced]
forced Telescope
delta1Gamma -- All variables are flexible

  -- Unify constructor target and given type (in Δ₁Γ)
  let conIxs   = Int -> Args -> Args
forall a. Int -> [a] -> [a]
drop (Args -> Int
forall a. Sized a => a -> Int
size Args
pars) Args
cixs
      givenIxs = Int -> Args -> Args
forall a. Subst a => Int -> a -> a
raise (Telescope -> Int
forall a. Sized a => a -> Int
size Telescope
gamma) Args
ixs

  -- Andrea 2019-07-17 propagate the Cohesion to the equation telescope
  -- TODO: should we propagate the modality in general?
  -- See also LHS checking.
  dtype <- addContext delta1 $ do
         let updCoh = Cohesion -> Cohesion -> Cohesion
composeCohesion (ArgInfo -> Cohesion
forall a. LensCohesion a => a -> Cohesion
getCohesion ArgInfo
info)
         TelV dtel dt <- telView dtype
         return $ abstract (mapCohesion updCoh <$> dtel) dt
  dsort <- addContext delta1 $ reduce (getSort dtype)

  let withKIfStrict = Bool
-> (ExceptT SplitError (TCMT IO) FullUnificationResult
    -> ExceptT SplitError (TCMT IO) FullUnificationResult)
-> ExceptT SplitError (TCMT IO) FullUnificationResult
-> ExceptT SplitError (TCMT IO) FullUnificationResult
forall b a. IsBool b => b -> (a -> a) -> a -> a
applyWhen (Sort -> Bool
forall t. Sort' t -> Bool
isStrictDataSort Sort
dsort) ((ExceptT SplitError (TCMT IO) FullUnificationResult
  -> ExceptT SplitError (TCMT IO) FullUnificationResult)
 -> ExceptT SplitError (TCMT IO) FullUnificationResult
 -> ExceptT SplitError (TCMT IO) FullUnificationResult)
-> (ExceptT SplitError (TCMT IO) FullUnificationResult
    -> ExceptT SplitError (TCMT IO) FullUnificationResult)
-> ExceptT SplitError (TCMT IO) FullUnificationResult
-> ExceptT SplitError (TCMT IO) FullUnificationResult
forall a b. (a -> b) -> a -> b
$ Lens' TCEnv Bool
-> (Bool -> Bool)
-> ExceptT SplitError (TCMT IO) FullUnificationResult
-> ExceptT SplitError (TCMT IO) FullUnificationResult
forall (m :: * -> *) a b.
MonadTCEnv m =>
Lens' TCEnv a -> (a -> a) -> m b -> m b
locallyTC (Bool -> f Bool) -> TCEnv -> f TCEnv
Lens' TCEnv Bool
eSplitOnStrict ((Bool -> Bool)
 -> ExceptT SplitError (TCMT IO) FullUnificationResult
 -> ExceptT SplitError (TCMT IO) FullUnificationResult)
-> (Bool -> Bool)
-> ExceptT SplitError (TCMT IO) FullUnificationResult
-> ExceptT SplitError (TCMT IO) FullUnificationResult
forall a b. (a -> b) -> a -> b
$ Bool -> Bool -> Bool
forall a b. a -> b -> a
const Bool
True

  -- Should we attempt to compute a left inverse for this clause? When
  -- --cubical-compatible --flat-split is given, we don't generate a
  -- left inverse (at all). This means that, when the coverage checker
  -- gets to the clause this was in, it won't generate a (malformed!)
  -- transpX clause for @♭ matching.
  -- TODO(Amy): properly support transpX when @♭ stuff is in the
  -- context.
  let flatSplit = Bool -> NoLeftInv -> Maybe NoLeftInv
forall a. Bool -> a -> Maybe a
boolToMaybe (ArgInfo -> Cohesion
forall a. LensCohesion a => a -> Cohesion
getCohesion ArgInfo
info Cohesion -> Cohesion -> Bool
forall a. Eq a => a -> a -> Bool
== Cohesion
Flat) NoLeftInv
SplitOnFlat

  r <- withKIfStrict $ lift $
         Bench.billTo [Bench.Coverage, Bench.UnifyIndices] $
           unifyIndices' flatSplit
             delta1Gamma
             flex
             (raise (size gamma) dtype)
             conIxs
             givenIxs

  TelV eqTel _ <- telView $ (raise (size gamma) dtype)

  let stuck Maybe Blocker
b [UnificationFailure]
errs = do
        ExceptT SplitError (TCMT IO) ()
debugCantSplit
        SplitError -> CoverM (Maybe (SplitClause, IInfo))
forall a. SplitError -> ExceptT SplitError (TCMT IO) a
forall e (m :: * -> *) a. MonadError e m => e -> m a
throwError (SplitError -> CoverM (Maybe (SplitClause, IInfo)))
-> SplitError -> CoverM (Maybe (SplitClause, IInfo))
forall a b. (a -> b) -> a -> b
$ Maybe Blocker
-> QName
-> Telescope
-> Args
-> Args
-> [UnificationFailure]
-> SplitError
UnificationStuck Maybe Blocker
b (ConHead -> QName
conName ConHead
con) (Telescope
delta1 Telescope -> Telescope -> Telescope
forall t. Abstract t => Telescope -> t -> t
`abstract` Telescope
gamma) Args
conIxs Args
givenIxs [UnificationFailure]
errs


  case r of
    NoUnify {} -> ExceptT SplitError (TCMT IO) ()
debugNoUnify ExceptT SplitError (TCMT IO) ()
-> Maybe (SplitClause, IInfo)
-> CoverM (Maybe (SplitClause, IInfo))
forall (f :: * -> *) a b. Functor f => f a -> b -> f b
$> Maybe (SplitClause, IInfo)
forall a. Maybe a
Nothing

    UnifyBlocked Blocker
block -> Maybe Blocker
-> [UnificationFailure] -> CoverM (Maybe (SplitClause, IInfo))
stuck (Blocker -> Maybe Blocker
forall a. a -> Maybe a
Just Blocker
block) []

    UnifyStuck [UnificationFailure]
errs -> Maybe Blocker
-> [UnificationFailure] -> CoverM (Maybe (SplitClause, IInfo))
stuck Maybe Blocker
forall a. Maybe a
Nothing [UnificationFailure]
errs

    Unifies (Telescope
delta1',PatternSubstitution
rho0,NAPs
eqs,Either NoLeftInv (Substitution' Term, Substitution' Term)
tauInv) -> do

      let unifyInfo :: IInfo
unifyInfo | Type Level
_ <- Sort
dsort     -- only types of sort Type l have trX constructors:
                                          -- re #3733: update if we add transp for other sorts.
                    , Bool -> Bool
not (Bool -> Bool) -> Bool -> Bool
forall a b. (a -> b) -> a -> b
$ Args -> Bool
forall a. Null a => a -> Bool
null (Args -> Bool) -> Args -> Bool
forall a b. (a -> b) -> a -> b
$ Args
conIxs -- no point propagating this info if trivial?
                    , Right (Substitution' Term
tau,Substitution' Term
leftInv) <- Either NoLeftInv (Substitution' Term, Substitution' Term)
tauInv
            = UnifyEquiv -> IInfo
TheInfo (UnifyEquiv -> IInfo) -> UnifyEquiv -> IInfo
forall a b. (a -> b) -> a -> b
$ Telescope
-> Telescope
-> Telescope
-> [Term]
-> [Term]
-> PatternSubstitution
-> Substitution' Term
-> Substitution' Term
-> UnifyEquiv
UE Telescope
delta1Gamma Telescope
delta1' Telescope
eqTel ((Arg Term -> Term) -> Args -> [Term]
forall a b. (a -> b) -> [a] -> [b]
map Arg Term -> Term
forall e. Arg e -> e
unArg Args
conIxs) ((Arg Term -> Term) -> Args -> [Term]
forall a b. (a -> b) -> [a] -> [b]
map Arg Term -> Term
forall e. Arg e -> e
unArg Args
givenIxs) PatternSubstitution
rho0 Substitution' Term
tau Substitution' Term
leftInv
                    | Bool
otherwise
            = IInfo
NoInfo

      case Either NoLeftInv (Substitution' Term, Substitution' Term)
tauInv of
        Right{} -> () -> ExceptT SplitError (TCMT IO) ()
forall a. a -> ExceptT SplitError (TCMT IO) a
forall (m :: * -> *) a. Monad m => a -> m a
return ()
        Left NoLeftInv
SplitOnStrict -> () -> ExceptT SplitError (TCMT IO) ()
forall a. a -> ExceptT SplitError (TCMT IO) a
forall (m :: * -> *) a. Monad m => a -> m a
return ()
        Left NoLeftInv
x -> do
          ExceptT SplitError (TCMT IO) Bool
-> ExceptT SplitError (TCMT IO) ()
-> ExceptT SplitError (TCMT IO) ()
forall (m :: * -> *). Monad m => m Bool -> m () -> m ()
whenM ExceptT SplitError (TCMT IO) Bool
forall (m :: * -> *). HasOptions m => m Bool
cubicalCompatibleOption (ExceptT SplitError (TCMT IO) ()
 -> ExceptT SplitError (TCMT IO) ())
-> ExceptT SplitError (TCMT IO) ()
-> ExceptT SplitError (TCMT IO) ()
forall a b. (a -> b) -> a -> b
$ do
            -- re #3733: TODO better error msg.
            TCMT IO () -> ExceptT SplitError (TCMT IO) ()
forall (m :: * -> *) a. Monad m => m a -> ExceptT SplitError m a
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (TCMT IO () -> ExceptT SplitError (TCMT IO) ())
-> TCMT IO () -> ExceptT SplitError (TCMT IO) ()
forall a b. (a -> b) -> a -> b
$ Warning -> TCMT IO ()
forall (m :: * -> *).
(HasCallStack, MonadWarning m) =>
Warning -> m ()
warning (Warning -> TCMT IO ()) -> (Doc -> Warning) -> Doc -> TCMT IO ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Doc -> Warning
UnsupportedIndexedMatch (Doc -> TCMT IO ()) -> TCMT IO Doc -> TCMT IO ()
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< NoLeftInv -> TCMT IO Doc
forall a (m :: * -> *). (PrettyTCM a, MonadPretty m) => a -> m Doc
forall (m :: * -> *). MonadPretty m => NoLeftInv -> m Doc
prettyTCM NoLeftInv
x

      [Char] -> PatternSubstitution -> ExceptT SplitError (TCMT IO) ()
forall {tcm :: * -> *} {a}.
(MonadTCM tcm, PrettyTCM a) =>
[Char] -> a -> tcm ()
debugSubst [Char]
"rho0" PatternSubstitution
rho0

      let rho0' :: Substitution' SplitPattern
rho0' = PatternSubstitution -> Substitution' SplitPattern
toSplitPSubst PatternSubstitution
rho0

      -- We have Δ₁' ⊢ ρ₀ : Δ₁Γ, so split it into the part for Δ₁ and the part for Γ
      let (Substitution' SplitPattern
rho1,Substitution' SplitPattern
rho2) = Int
-> Substitution' SplitPattern
-> (Substitution' SplitPattern, Substitution' SplitPattern)
forall a.
Int -> Substitution' a -> (Substitution' a, Substitution' a)
splitS (Telescope -> Int
forall a. Sized a => a -> Int
size Telescope
gamma) (Substitution' SplitPattern
 -> (Substitution' SplitPattern, Substitution' SplitPattern))
-> Substitution' SplitPattern
-> (Substitution' SplitPattern, Substitution' SplitPattern)
forall a b. (a -> b) -> a -> b
$ Substitution' SplitPattern
rho0'

      -- Andreas, 2015-05-01  I guess it is fine to use no @conPType@
      -- as the result of splitting is never used further down the pipeline.
      -- After splitting, Agda reloads the file.
      -- Andreas, 2017-09-03, issue #2729: remember that pattern was generated by case split.
      let cpi :: ConPatternInfo
cpi  = ConPatternInfo
noConPatternInfo{ conPInfo = PatternInfo PatOSplit [] , conPRecord = True }
          conp :: SplitPattern
conp = ConHead
-> ConPatternInfo -> [NamedArg SplitPattern] -> SplitPattern
forall x.
ConHead -> ConPatternInfo -> [NamedArg (Pattern' x)] -> Pattern' x
ConP ConHead
con ConPatternInfo
cpi ([NamedArg SplitPattern] -> SplitPattern)
-> [NamedArg SplitPattern] -> SplitPattern
forall a b. (a -> b) -> a -> b
$ Substitution' (SubstArg [NamedArg SplitPattern])
-> [NamedArg SplitPattern] -> [NamedArg SplitPattern]
forall a. Subst a => Substitution' (SubstArg a) -> a -> a
applySubst Substitution' SplitPattern
Substitution' (SubstArg [NamedArg SplitPattern])
rho0' ([NamedArg SplitPattern] -> [NamedArg SplitPattern])
-> [NamedArg SplitPattern] -> [NamedArg SplitPattern]
forall a b. (a -> b) -> a -> b
$
                   (NamedArg SplitPattern -> NamedArg SplitPattern)
-> [NamedArg SplitPattern] -> [NamedArg SplitPattern]
forall a b. (a -> b) -> [a] -> [b]
map ((ArgInfo -> ArgInfo)
-> NamedArg SplitPattern -> NamedArg SplitPattern
forall a. LensArgInfo a => (ArgInfo -> ArgInfo) -> a -> a
mapArgInfo ArgInfo -> ArgInfo
hiddenInserted) ([NamedArg SplitPattern] -> [NamedArg SplitPattern])
-> [NamedArg SplitPattern] -> [NamedArg SplitPattern]
forall a b. (a -> b) -> a -> b
$ (forall a1. DeBruijn a1 => Telescope -> [NamedArg a1])
-> Telescope -> Boundary -> [NamedArg SplitPattern]
forall a.
DeBruijn a =>
(forall a1. DeBruijn a1 => Telescope -> [NamedArg a1])
-> Telescope -> Boundary -> [NamedArg (Pattern' a)]
telePatterns' (Telescope -> Telescope -> [NamedArg a1]
forall a. DeBruijn a => Telescope -> Telescope -> [NamedArg a]
tele2NamedArgs Telescope
gamma0) Telescope
gamma Boundary
boundary
          -- Andreas, 2016-09-08, issue #2166: use gamma0 for correct argument names

      -- Compute final context and substitution
      let rho3 :: Substitution' SplitPattern
rho3    = SplitPattern
-> Substitution' SplitPattern -> Substitution' SplitPattern
forall a. DeBruijn a => a -> Substitution' a -> Substitution' a
consS SplitPattern
conp Substitution' SplitPattern
rho1            -- Δ₁' ⊢ ρ₃ : Δ₁(x:D)
          delta2' :: Telescope
delta2' = Substitution' SplitPattern -> Telescope -> Telescope
forall a. TermSubst a => Substitution' SplitPattern -> a -> a
applySplitPSubst Substitution' SplitPattern
rho3 Telescope
delta2  -- Δ₂' = Δ₂ρ₃
          delta' :: Telescope
delta'  = Telescope
delta1' Telescope -> Telescope -> Telescope
forall t. Abstract t => Telescope -> t -> t
`abstract` Telescope
delta2' -- Δ'  = Δ₁'Δ₂'
          rho :: Substitution' SplitPattern
rho     = Int -> Substitution' SplitPattern -> Substitution' SplitPattern
forall a. Int -> Substitution' a -> Substitution' a
liftS (Telescope -> Int
forall a. Sized a => a -> Int
size Telescope
delta2) Substitution' SplitPattern
rho3   -- Δ' ⊢ ρ : Δ₁(x:D)Δ₂

      [Char] -> Telescope -> ExceptT SplitError (TCMT IO) ()
forall {tcm :: * -> *} {a}.
(MonadTCM tcm, PrettyTCM a) =>
[Char] -> a -> tcm ()
debugTel [Char]
"delta'" Telescope
delta'
      [Char]
-> Substitution' SplitPattern -> ExceptT SplitError (TCMT IO) ()
forall {tcm :: * -> *} {a}.
(MonadTCM tcm, PrettyTCM a) =>
[Char] -> a -> tcm ()
debugSubst [Char]
"rho" Substitution' SplitPattern
rho
      Telescope
-> [NamedArg SplitPattern] -> ExceptT SplitError (TCMT IO) ()
forall {tcm :: * -> *} {b}.
(MonadTCM tcm, AddContext b) =>
b -> [NamedArg SplitPattern] -> tcm ()
debugPs Telescope
tel [NamedArg SplitPattern]
ps

      -- Apply the substitution
      let ps' :: [NamedArg SplitPattern]
ps' = Substitution' (SubstArg [NamedArg SplitPattern])
-> [NamedArg SplitPattern] -> [NamedArg SplitPattern]
forall a. Subst a => Substitution' (SubstArg a) -> a -> a
applySubst Substitution' SplitPattern
Substitution' (SubstArg [NamedArg SplitPattern])
rho [NamedArg SplitPattern]
ps
      Telescope
-> [NamedArg SplitPattern] -> ExceptT SplitError (TCMT IO) ()
forall {tcm :: * -> *} {b}.
(MonadTCM tcm, AddContext b) =>
b -> [NamedArg SplitPattern] -> tcm ()
debugPlugged Telescope
delta' [NamedArg SplitPattern]
ps'

      let cps' :: Map CheckpointId (Substitution' Term)
cps'  = Substitution' SplitPattern
-> Map CheckpointId (Substitution' Term)
-> Map CheckpointId (Substitution' Term)
forall a. TermSubst a => Substitution' SplitPattern -> a -> a
applySplitPSubst Substitution' SplitPattern
rho Map CheckpointId (Substitution' Term)
cps

      Maybe (SplitClause, IInfo) -> CoverM (Maybe (SplitClause, IInfo))
forall a. a -> ExceptT SplitError (TCMT IO) a
forall (m :: * -> *) a. Monad m => a -> m a
return (Maybe (SplitClause, IInfo) -> CoverM (Maybe (SplitClause, IInfo)))
-> Maybe (SplitClause, IInfo)
-> CoverM (Maybe (SplitClause, IInfo))
forall a b. (a -> b) -> a -> b
$ (SplitClause, IInfo) -> Maybe (SplitClause, IInfo)
forall a. a -> Maybe a
Just ((SplitClause, IInfo) -> Maybe (SplitClause, IInfo))
-> (SplitClause -> (SplitClause, IInfo))
-> SplitClause
-> Maybe (SplitClause, IInfo)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (,IInfo
unifyInfo) (SplitClause -> Maybe (SplitClause, IInfo))
-> SplitClause -> Maybe (SplitClause, IInfo)
forall a b. (a -> b) -> a -> b
$ Telescope
-> [NamedArg SplitPattern]
-> Substitution' SplitPattern
-> Map CheckpointId (Substitution' Term)
-> Maybe (Dom Type)
-> SplitClause
SClause Telescope
delta' [NamedArg SplitPattern]
ps' Substitution' SplitPattern
rho Map CheckpointId (Substitution' Term)
cps' Maybe (Dom Type)
forall a. Maybe a
Nothing -- target fixed later

  where
    debugInit :: ConHead
-> Type
-> QName
-> Args
-> Args
-> Args
-> Telescope
-> Telescope
-> Telescope
-> Telescope
-> [NamedArg SplitPattern]
-> Int
-> ExceptT SplitError (TCMT IO) ()
debugInit ConHead
con Type
ctype QName
d Args
pars Args
ixs Args
cixs Telescope
delta1 Telescope
delta2 Telescope
gamma Telescope
tel [NamedArg SplitPattern]
ps Int
hix = TCMT IO () -> ExceptT SplitError (TCMT IO) ()
forall a. TCM a -> ExceptT SplitError (TCMT IO) a
forall (tcm :: * -> *) a. MonadTCM tcm => TCM a -> tcm a
liftTCM (TCMT IO () -> ExceptT SplitError (TCMT IO) ())
-> TCMT IO () -> ExceptT SplitError (TCMT IO) ()
forall a b. (a -> b) -> a -> b
$ do
      [Char] -> Int -> TCMT IO Doc -> TCMT IO ()
forall (m :: * -> *).
MonadDebug m =>
[Char] -> Int -> TCMT IO Doc -> m ()
reportSDoc [Char]
"tc.cover.split.con" Int
20 (TCMT IO Doc -> TCMT IO ()) -> TCMT IO Doc -> TCMT IO ()
forall a b. (a -> b) -> a -> b
$ [TCMT IO Doc] -> TCMT IO Doc
forall (m :: * -> *) (t :: * -> *).
(Applicative m, Foldable t) =>
t (m Doc) -> m Doc
vcat
        [ TCMT IO Doc
"computeNeighbourhood"
        , Int -> TCMT IO Doc -> TCMT IO Doc
forall (m :: * -> *). Functor m => Int -> m Doc -> m Doc
nest Int
2 (TCMT IO Doc -> TCMT IO Doc) -> TCMT IO Doc -> TCMT IO Doc
forall a b. (a -> b) -> a -> b
$ [TCMT IO Doc] -> TCMT IO Doc
forall (m :: * -> *) (t :: * -> *).
(Applicative m, Foldable t) =>
t (m Doc) -> m Doc
vcat
          [ TCMT IO Doc
"context=" TCMT IO Doc -> TCMT IO Doc -> TCMT IO Doc
forall (m :: * -> *). Applicative m => m Doc -> m Doc -> m Doc
<+> (TCMT IO Doc -> TCMT IO Doc
forall (tcm :: * -> *) a.
(MonadTCEnv tcm, ReadTCState tcm) =>
tcm a -> tcm a
inTopContext (TCMT IO Doc -> TCMT IO Doc)
-> (Telescope -> TCMT IO Doc) -> Telescope -> TCMT IO Doc
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Telescope -> TCMT IO Doc
forall a (m :: * -> *). (PrettyTCM a, MonadPretty m) => a -> m Doc
forall (m :: * -> *). MonadPretty m => Telescope -> m Doc
prettyTCM (Telescope -> TCMT IO Doc) -> TCMT IO Telescope -> TCMT IO Doc
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< TCMT IO Telescope
forall (m :: * -> *). (Applicative m, MonadTCEnv m) => m Telescope
getContextTelescope)
          , TCMT IO Doc
"con    =" TCMT IO Doc -> TCMT IO Doc -> TCMT IO Doc
forall (m :: * -> *). Applicative m => m Doc -> m Doc -> m Doc
<+> ConHead -> TCMT IO Doc
forall a (m :: * -> *). (PrettyTCM a, MonadPretty m) => a -> m Doc
forall (m :: * -> *). MonadPretty m => ConHead -> m Doc
prettyTCM ConHead
con
          , TCMT IO Doc
"ctype  =" TCMT IO Doc -> TCMT IO Doc -> TCMT IO Doc
forall (m :: * -> *). Applicative m => m Doc -> m Doc -> m Doc
<+> Type -> TCMT IO Doc
forall a (m :: * -> *). (PrettyTCM a, MonadPretty m) => a -> m Doc
forall (m :: * -> *). MonadPretty m => Type -> m Doc
prettyTCM Type
ctype
          , TCMT IO Doc
"ps     =" TCMT IO Doc -> TCMT IO Doc -> TCMT IO Doc
forall (m :: * -> *). Applicative m => m Doc -> m Doc -> m Doc
<+> do TCMT IO Doc -> TCMT IO Doc
forall (tcm :: * -> *) a.
(MonadTCEnv tcm, ReadTCState tcm) =>
tcm a -> tcm a
inTopContext (TCMT IO Doc -> TCMT IO Doc) -> TCMT IO Doc -> TCMT IO Doc
forall a b. (a -> b) -> a -> b
$ Telescope -> TCMT IO Doc -> TCMT IO Doc
forall b (m :: * -> *) a.
(AddContext b, MonadAddContext m) =>
b -> m a -> m a
forall (m :: * -> *) a.
MonadAddContext m =>
Telescope -> m a -> m a
addContext Telescope
tel (TCMT IO Doc -> TCMT IO Doc) -> TCMT IO Doc -> TCMT IO Doc
forall a b. (a -> b) -> a -> b
$ NAPs -> TCMT IO Doc
forall (m :: * -> *). MonadPretty m => NAPs -> m Doc
prettyTCMPatternList (NAPs -> TCMT IO Doc) -> NAPs -> TCMT IO Doc
forall a b. (a -> b) -> a -> b
$ [NamedArg SplitPattern] -> NAPs
fromSplitPatterns [NamedArg SplitPattern]
ps
          , TCMT IO Doc
"d      =" TCMT IO Doc -> TCMT IO Doc -> TCMT IO Doc
forall (m :: * -> *). Applicative m => m Doc -> m Doc -> m Doc
<+> QName -> TCMT IO Doc
forall a (m :: * -> *). (PrettyTCM a, MonadPretty m) => a -> m Doc
forall (m :: * -> *). MonadPretty m => QName -> m Doc
prettyTCM QName
d
          , TCMT IO Doc
"pars   =" TCMT IO Doc -> TCMT IO Doc -> TCMT IO Doc
forall (m :: * -> *). Applicative m => m Doc -> m Doc -> m Doc
<+> do [TCMT IO Doc] -> TCMT IO Doc
forall (m :: * -> *) (t :: * -> *).
(Applicative m, Semigroup (m Doc), Foldable t) =>
t (m Doc) -> m Doc
prettyList ([TCMT IO Doc] -> TCMT IO Doc) -> [TCMT IO Doc] -> TCMT IO Doc
forall a b. (a -> b) -> a -> b
$ (Arg Term -> TCMT IO Doc) -> Args -> [TCMT IO Doc]
forall a b. (a -> b) -> [a] -> [b]
map Arg Term -> TCMT IO Doc
forall a (m :: * -> *). (PrettyTCM a, MonadPretty m) => a -> m Doc
forall (m :: * -> *). MonadPretty m => Arg Term -> m Doc
prettyTCM Args
pars
          , TCMT IO Doc
"ixs    =" TCMT IO Doc -> TCMT IO Doc -> TCMT IO Doc
forall (m :: * -> *). Applicative m => m Doc -> m Doc -> m Doc
<+> do Telescope -> TCMT IO Doc -> TCMT IO Doc
forall b (m :: * -> *) a.
(AddContext b, MonadAddContext m) =>
b -> m a -> m a
forall (m :: * -> *) a.
MonadAddContext m =>
Telescope -> m a -> m a
addContext Telescope
delta1 (TCMT IO Doc -> TCMT IO Doc) -> TCMT IO Doc -> TCMT IO Doc
forall a b. (a -> b) -> a -> b
$ [TCMT IO Doc] -> TCMT IO Doc
forall (m :: * -> *) (t :: * -> *).
(Applicative m, Semigroup (m Doc), Foldable t) =>
t (m Doc) -> m Doc
prettyList ([TCMT IO Doc] -> TCMT IO Doc) -> [TCMT IO Doc] -> TCMT IO Doc
forall a b. (a -> b) -> a -> b
$ (Arg Term -> TCMT IO Doc) -> Args -> [TCMT IO Doc]
forall a b. (a -> b) -> [a] -> [b]
map Arg Term -> TCMT IO Doc
forall a (m :: * -> *). (PrettyTCM a, MonadPretty m) => a -> m Doc
forall (m :: * -> *). MonadPretty m => Arg Term -> m Doc
prettyTCM Args
ixs
          , TCMT IO Doc
"cixs   =" TCMT IO Doc -> TCMT IO Doc -> TCMT IO Doc
forall (m :: * -> *). Applicative m => m Doc -> m Doc -> m Doc
<+> do Telescope -> TCMT IO Doc -> TCMT IO Doc
forall b (m :: * -> *) a.
(AddContext b, MonadAddContext m) =>
b -> m a -> m a
forall (m :: * -> *) a.
MonadAddContext m =>
Telescope -> m a -> m a
addContext Telescope
gamma  (TCMT IO Doc -> TCMT IO Doc) -> TCMT IO Doc -> TCMT IO Doc
forall a b. (a -> b) -> a -> b
$ [TCMT IO Doc] -> TCMT IO Doc
forall (m :: * -> *) (t :: * -> *).
(Applicative m, Semigroup (m Doc), Foldable t) =>
t (m Doc) -> m Doc
prettyList ([TCMT IO Doc] -> TCMT IO Doc) -> [TCMT IO Doc] -> TCMT IO Doc
forall a b. (a -> b) -> a -> b
$ (Arg Term -> TCMT IO Doc) -> Args -> [TCMT IO Doc]
forall a b. (a -> b) -> [a] -> [b]
map Arg Term -> TCMT IO Doc
forall a (m :: * -> *). (PrettyTCM a, MonadPretty m) => a -> m Doc
forall (m :: * -> *). MonadPretty m => Arg Term -> m Doc
prettyTCM Args
cixs
          , TCMT IO Doc
"delta1 =" TCMT IO Doc -> TCMT IO Doc -> TCMT IO Doc
forall (m :: * -> *). Applicative m => m Doc -> m Doc -> m Doc
<+> do TCMT IO Doc -> TCMT IO Doc
forall (tcm :: * -> *) a.
(MonadTCEnv tcm, ReadTCState tcm) =>
tcm a -> tcm a
inTopContext (TCMT IO Doc -> TCMT IO Doc) -> TCMT IO Doc -> TCMT IO Doc
forall a b. (a -> b) -> a -> b
$ Telescope -> TCMT IO Doc
forall a (m :: * -> *). (PrettyTCM a, MonadPretty m) => a -> m Doc
forall (m :: * -> *). MonadPretty m => Telescope -> m Doc
prettyTCM Telescope
delta1
          , TCMT IO Doc
"delta2 =" TCMT IO Doc -> TCMT IO Doc -> TCMT IO Doc
forall (m :: * -> *). Applicative m => m Doc -> m Doc -> m Doc
<+> do TCMT IO Doc -> TCMT IO Doc
forall (tcm :: * -> *) a.
(MonadTCEnv tcm, ReadTCState tcm) =>
tcm a -> tcm a
inTopContext (TCMT IO Doc -> TCMT IO Doc) -> TCMT IO Doc -> TCMT IO Doc
forall a b. (a -> b) -> a -> b
$ Telescope -> TCMT IO Doc -> TCMT IO Doc
forall b (m :: * -> *) a.
(AddContext b, MonadAddContext m) =>
b -> m a -> m a
forall (m :: * -> *) a.
MonadAddContext m =>
Telescope -> m a -> m a
addContext Telescope
delta1 (TCMT IO Doc -> TCMT IO Doc) -> TCMT IO Doc -> TCMT IO Doc
forall a b. (a -> b) -> a -> b
$ [Char] -> TCMT IO Doc -> TCMT IO Doc
forall b (m :: * -> *) a.
(AddContext b, MonadAddContext m) =>
b -> m a -> m a
forall (m :: * -> *) a. MonadAddContext m => [Char] -> m a -> m a
addContext [Char]
n (TCMT IO Doc -> TCMT IO Doc) -> TCMT IO Doc -> TCMT IO Doc
forall a b. (a -> b) -> a -> b
$ Telescope -> TCMT IO Doc
forall a (m :: * -> *). (PrettyTCM a, MonadPretty m) => a -> m Doc
forall (m :: * -> *). MonadPretty m => Telescope -> m Doc
prettyTCM Telescope
delta2
          , TCMT IO Doc
"gamma  =" TCMT IO Doc -> TCMT IO Doc -> TCMT IO Doc
forall (m :: * -> *). Applicative m => m Doc -> m Doc -> m Doc
<+> do TCMT IO Doc -> TCMT IO Doc
forall (tcm :: * -> *) a.
(MonadTCEnv tcm, ReadTCState tcm) =>
tcm a -> tcm a
inTopContext (TCMT IO Doc -> TCMT IO Doc) -> TCMT IO Doc -> TCMT IO Doc
forall a b. (a -> b) -> a -> b
$ Telescope -> TCMT IO Doc -> TCMT IO Doc
forall b (m :: * -> *) a.
(AddContext b, MonadAddContext m) =>
b -> m a -> m a
forall (m :: * -> *) a.
MonadAddContext m =>
Telescope -> m a -> m a
addContext Telescope
delta1 (TCMT IO Doc -> TCMT IO Doc) -> TCMT IO Doc -> TCMT IO Doc
forall a b. (a -> b) -> a -> b
$ Telescope -> TCMT IO Doc
forall a (m :: * -> *). (PrettyTCM a, MonadPretty m) => a -> m Doc
forall (m :: * -> *). MonadPretty m => Telescope -> m Doc
prettyTCM Telescope
gamma
          , TCMT IO Doc
"tel  =" TCMT IO Doc -> TCMT IO Doc -> TCMT IO Doc
forall (m :: * -> *). Applicative m => m Doc -> m Doc -> m Doc
<+> do TCMT IO Doc -> TCMT IO Doc
forall (tcm :: * -> *) a.
(MonadTCEnv tcm, ReadTCState tcm) =>
tcm a -> tcm a
inTopContext (TCMT IO Doc -> TCMT IO Doc) -> TCMT IO Doc -> TCMT IO Doc
forall a b. (a -> b) -> a -> b
$ Telescope -> TCMT IO Doc
forall a (m :: * -> *). (PrettyTCM a, MonadPretty m) => a -> m Doc
forall (m :: * -> *). MonadPretty m => Telescope -> m Doc
prettyTCM Telescope
tel
          , TCMT IO Doc
"hix    =" TCMT IO Doc -> TCMT IO Doc -> TCMT IO Doc
forall (m :: * -> *). Applicative m => m Doc -> m Doc -> m Doc
<+> [Char] -> TCMT IO Doc
forall (m :: * -> *). Applicative m => [Char] -> m Doc
text (Int -> [Char]
forall a. Show a => a -> [Char]
show Int
hix)
          ]
        ]
      [Char] -> Int -> TCMT IO Doc -> TCMT IO ()
forall (m :: * -> *).
MonadDebug m =>
[Char] -> Int -> TCMT IO Doc -> m ()
reportSDoc [Char]
"tc.cover.split.con" Int
70 (TCMT IO Doc -> TCMT IO ()) -> TCMT IO Doc -> TCMT IO ()
forall a b. (a -> b) -> a -> b
$ [TCMT IO Doc] -> TCMT IO Doc
forall (m :: * -> *) (t :: * -> *).
(Applicative m, Foldable t) =>
t (m Doc) -> m Doc
vcat
        [ TCMT IO Doc
"computeNeighbourhood"
        , Int -> TCMT IO Doc -> TCMT IO Doc
forall (m :: * -> *). Functor m => Int -> m Doc -> m Doc
nest Int
2 (TCMT IO Doc -> TCMT IO Doc) -> TCMT IO Doc -> TCMT IO Doc
forall a b. (a -> b) -> a -> b
$ [TCMT IO Doc] -> TCMT IO Doc
forall (m :: * -> *) (t :: * -> *).
(Applicative m, Foldable t) =>
t (m Doc) -> m Doc
vcat
          [ TCMT IO Doc
"context=" TCMT IO Doc -> TCMT IO Doc -> TCMT IO Doc
forall (m :: * -> *). Applicative m => m Doc -> m Doc -> m Doc
<+> (TCMT IO Doc -> TCMT IO Doc
forall (tcm :: * -> *) a.
(MonadTCEnv tcm, ReadTCState tcm) =>
tcm a -> tcm a
inTopContext (TCMT IO Doc -> TCMT IO Doc)
-> (Telescope -> TCMT IO Doc) -> Telescope -> TCMT IO Doc
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ([Char] -> TCMT IO Doc
forall (m :: * -> *). Applicative m => [Char] -> m Doc
text ([Char] -> TCMT IO Doc)
-> (Telescope -> [Char]) -> Telescope -> TCMT IO Doc
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Telescope -> [Char]
forall a. Show a => a -> [Char]
show) (Telescope -> TCMT IO Doc) -> TCMT IO Telescope -> TCMT IO Doc
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< TCMT IO Telescope
forall (m :: * -> *). (Applicative m, MonadTCEnv m) => m Telescope
getContextTelescope)
          , TCMT IO Doc
"con    =" TCMT IO Doc -> TCMT IO Doc -> TCMT IO Doc
forall (m :: * -> *). Applicative m => m Doc -> m Doc -> m Doc
<+> ([Char] -> TCMT IO Doc
forall (m :: * -> *). Applicative m => [Char] -> m Doc
text ([Char] -> TCMT IO Doc)
-> (ConHead -> [Char]) -> ConHead -> TCMT IO Doc
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ConHead -> [Char]
forall a. Show a => a -> [Char]
show) ConHead
con
          , TCMT IO Doc
"ctype  =" TCMT IO Doc -> TCMT IO Doc -> TCMT IO Doc
forall (m :: * -> *). Applicative m => m Doc -> m Doc -> m Doc
<+> ([Char] -> TCMT IO Doc
forall (m :: * -> *). Applicative m => [Char] -> m Doc
text ([Char] -> TCMT IO Doc) -> (Type -> [Char]) -> Type -> TCMT IO Doc
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Type -> [Char]
forall a. Show a => a -> [Char]
show) Type
ctype
          , TCMT IO Doc
"ps     =" TCMT IO Doc -> TCMT IO Doc -> TCMT IO Doc
forall (m :: * -> *). Applicative m => m Doc -> m Doc -> m Doc
<+> ([Char] -> TCMT IO Doc
forall (m :: * -> *). Applicative m => [Char] -> m Doc
text ([Char] -> TCMT IO Doc)
-> ([NamedArg SplitPattern] -> [Char])
-> [NamedArg SplitPattern]
-> TCMT IO Doc
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [NamedArg SplitPattern] -> [Char]
forall a. Show a => a -> [Char]
show) [NamedArg SplitPattern]
ps
          , TCMT IO Doc
"d      =" TCMT IO Doc -> TCMT IO Doc -> TCMT IO Doc
forall (m :: * -> *). Applicative m => m Doc -> m Doc -> m Doc
<+> ([Char] -> TCMT IO Doc
forall (m :: * -> *). Applicative m => [Char] -> m Doc
text ([Char] -> TCMT IO Doc)
-> (QName -> [Char]) -> QName -> TCMT IO Doc
forall b c a. (b -> c) -> (a -> b) -> a -> c
. QName -> [Char]
forall a. Show a => a -> [Char]
show) QName
d
          , TCMT IO Doc
"pars   =" TCMT IO Doc -> TCMT IO Doc -> TCMT IO Doc
forall (m :: * -> *). Applicative m => m Doc -> m Doc -> m Doc
<+> ([Char] -> TCMT IO Doc
forall (m :: * -> *). Applicative m => [Char] -> m Doc
text ([Char] -> TCMT IO Doc) -> (Args -> [Char]) -> Args -> TCMT IO Doc
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Args -> [Char]
forall a. Show a => a -> [Char]
show) Args
pars
          , TCMT IO Doc
"ixs    =" TCMT IO Doc -> TCMT IO Doc -> TCMT IO Doc
forall (m :: * -> *). Applicative m => m Doc -> m Doc -> m Doc
<+> ([Char] -> TCMT IO Doc
forall (m :: * -> *). Applicative m => [Char] -> m Doc
text ([Char] -> TCMT IO Doc) -> (Args -> [Char]) -> Args -> TCMT IO Doc
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Args -> [Char]
forall a. Show a => a -> [Char]
show) Args
ixs
          , TCMT IO Doc
"cixs   =" TCMT IO Doc -> TCMT IO Doc -> TCMT IO Doc
forall (m :: * -> *). Applicative m => m Doc -> m Doc -> m Doc
<+> ([Char] -> TCMT IO Doc
forall (m :: * -> *). Applicative m => [Char] -> m Doc
text ([Char] -> TCMT IO Doc) -> (Args -> [Char]) -> Args -> TCMT IO Doc
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Args -> [Char]
forall a. Show a => a -> [Char]
show) Args
cixs
          , TCMT IO Doc
"delta1 =" TCMT IO Doc -> TCMT IO Doc -> TCMT IO Doc
forall (m :: * -> *). Applicative m => m Doc -> m Doc -> m Doc
<+> ([Char] -> TCMT IO Doc
forall (m :: * -> *). Applicative m => [Char] -> m Doc
text ([Char] -> TCMT IO Doc)
-> (Telescope -> [Char]) -> Telescope -> TCMT IO Doc
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Telescope -> [Char]
forall a. Show a => a -> [Char]
show) Telescope
delta1
          , TCMT IO Doc
"delta2 =" TCMT IO Doc -> TCMT IO Doc -> TCMT IO Doc
forall (m :: * -> *). Applicative m => m Doc -> m Doc -> m Doc
<+> ([Char] -> TCMT IO Doc
forall (m :: * -> *). Applicative m => [Char] -> m Doc
text ([Char] -> TCMT IO Doc)
-> (Telescope -> [Char]) -> Telescope -> TCMT IO Doc
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Telescope -> [Char]
forall a. Show a => a -> [Char]
show) Telescope
delta2
          , TCMT IO Doc
"gamma  =" TCMT IO Doc -> TCMT IO Doc -> TCMT IO Doc
forall (m :: * -> *). Applicative m => m Doc -> m Doc -> m Doc
<+> ([Char] -> TCMT IO Doc
forall (m :: * -> *). Applicative m => [Char] -> m Doc
text ([Char] -> TCMT IO Doc)
-> (Telescope -> [Char]) -> Telescope -> TCMT IO Doc
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Telescope -> [Char]
forall a. Show a => a -> [Char]
show) Telescope
gamma
          , TCMT IO Doc
"hix    =" TCMT IO Doc -> TCMT IO Doc -> TCMT IO Doc
forall (m :: * -> *). Applicative m => m Doc -> m Doc -> m Doc
<+> [Char] -> TCMT IO Doc
forall (m :: * -> *). Applicative m => [Char] -> m Doc
text (Int -> [Char]
forall a. Show a => a -> [Char]
show Int
hix)
          ]
        ]

    debugNoUnify :: ExceptT SplitError (TCMT IO) ()
debugNoUnify =
      TCMT IO () -> ExceptT SplitError (TCMT IO) ()
forall a. TCM a -> ExceptT SplitError (TCMT IO) a
forall (tcm :: * -> *) a. MonadTCM tcm => TCM a -> tcm a
liftTCM (TCMT IO () -> ExceptT SplitError (TCMT IO) ())
-> TCMT IO () -> ExceptT SplitError (TCMT IO) ()
forall a b. (a -> b) -> a -> b
$ [Char] -> Int -> [Char] -> TCMT IO ()
forall (m :: * -> *).
MonadDebug m =>
[Char] -> Int -> [Char] -> m ()
reportSLn [Char]
"tc.cover.split.con" Int
20 [Char]
"  Constructor impossible!"

    debugCantSplit :: ExceptT SplitError (TCMT IO) ()
debugCantSplit =
      TCMT IO () -> ExceptT SplitError (TCMT IO) ()
forall a. TCM a -> ExceptT SplitError (TCMT IO) a
forall (tcm :: * -> *) a. MonadTCM tcm => TCM a -> tcm a
liftTCM (TCMT IO () -> ExceptT SplitError (TCMT IO) ())
-> TCMT IO () -> ExceptT SplitError (TCMT IO) ()
forall a b. (a -> b) -> a -> b
$ [Char] -> Int -> [Char] -> TCMT IO ()
forall (m :: * -> *).
MonadDebug m =>
[Char] -> Int -> [Char] -> m ()
reportSLn [Char]
"tc.cover.split.con" Int
20 [Char]
"  Bad split!"

    debugSubst :: [Char] -> a -> tcm ()
debugSubst [Char]
s a
sub =
      TCMT IO () -> tcm ()
forall a. TCM a -> tcm a
forall (tcm :: * -> *) a. MonadTCM tcm => TCM a -> tcm a
liftTCM (TCMT IO () -> tcm ()) -> TCMT IO () -> tcm ()
forall a b. (a -> b) -> a -> b
$ [Char] -> Int -> TCMT IO Doc -> TCMT IO ()
forall (m :: * -> *).
MonadDebug m =>
[Char] -> Int -> TCMT IO Doc -> m ()
reportSDoc [Char]
"tc.cover.split.con" Int
20 (TCMT IO Doc -> TCMT IO ()) -> TCMT IO Doc -> TCMT IO ()
forall a b. (a -> b) -> a -> b
$ Int -> TCMT IO Doc -> TCMT IO Doc
forall (m :: * -> *). Functor m => Int -> m Doc -> m Doc
nest Int
2 (TCMT IO Doc -> TCMT IO Doc) -> TCMT IO Doc -> TCMT IO Doc
forall a b. (a -> b) -> a -> b
$ [TCMT IO Doc] -> TCMT IO Doc
forall (m :: * -> *) (t :: * -> *).
(Applicative m, Foldable t) =>
t (m Doc) -> m Doc
vcat
        [ [Char] -> TCMT IO Doc
forall (m :: * -> *). Applicative m => [Char] -> m Doc
text ([Char]
s [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
" =") TCMT IO Doc -> TCMT IO Doc -> TCMT IO Doc
forall (m :: * -> *). Applicative m => m Doc -> m Doc -> m Doc
<+> a -> TCMT IO Doc
forall a (m :: * -> *). (PrettyTCM a, MonadPretty m) => a -> m Doc
forall (m :: * -> *). MonadPretty m => a -> m Doc
prettyTCM a
sub
        ]

    debugTel :: [Char] -> a -> tcm ()
debugTel [Char]
s a
tel =
      TCMT IO () -> tcm ()
forall a. TCM a -> tcm a
forall (tcm :: * -> *) a. MonadTCM tcm => TCM a -> tcm a
liftTCM (TCMT IO () -> tcm ()) -> TCMT IO () -> tcm ()
forall a b. (a -> b) -> a -> b
$ [Char] -> Int -> TCMT IO Doc -> TCMT IO ()
forall (m :: * -> *).
MonadDebug m =>
[Char] -> Int -> TCMT IO Doc -> m ()
reportSDoc [Char]
"tc.cover.split.con" Int
20 (TCMT IO Doc -> TCMT IO ()) -> TCMT IO Doc -> TCMT IO ()
forall a b. (a -> b) -> a -> b
$ Int -> TCMT IO Doc -> TCMT IO Doc
forall (m :: * -> *). Functor m => Int -> m Doc -> m Doc
nest Int
2 (TCMT IO Doc -> TCMT IO Doc) -> TCMT IO Doc -> TCMT IO Doc
forall a b. (a -> b) -> a -> b
$ [TCMT IO Doc] -> TCMT IO Doc
forall (m :: * -> *) (t :: * -> *).
(Applicative m, Foldable t) =>
t (m Doc) -> m Doc
vcat
        [ [Char] -> TCMT IO Doc
forall (m :: * -> *). Applicative m => [Char] -> m Doc
text ([Char]
s [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
" =") TCMT IO Doc -> TCMT IO Doc -> TCMT IO Doc
forall (m :: * -> *). Applicative m => m Doc -> m Doc -> m Doc
<+> a -> TCMT IO Doc
forall a (m :: * -> *). (PrettyTCM a, MonadPretty m) => a -> m Doc
forall (m :: * -> *). MonadPretty m => a -> m Doc
prettyTCM a
tel
        ]

    debugPs :: b -> [NamedArg SplitPattern] -> tcm ()
debugPs b
tel [NamedArg SplitPattern]
ps =
      TCMT IO () -> tcm ()
forall a. TCM a -> tcm a
forall (tcm :: * -> *) a. MonadTCM tcm => TCM a -> tcm a
liftTCM (TCMT IO () -> tcm ()) -> TCMT IO () -> tcm ()
forall a b. (a -> b) -> a -> b
$ [Char] -> Int -> TCMT IO Doc -> TCMT IO ()
forall (m :: * -> *).
MonadDebug m =>
[Char] -> Int -> TCMT IO Doc -> m ()
reportSDoc [Char]
"tc.cover.split.con" Int
20 (TCMT IO Doc -> TCMT IO ()) -> TCMT IO Doc -> TCMT IO ()
forall a b. (a -> b) -> a -> b
$
        TCMT IO Doc -> TCMT IO Doc
forall (tcm :: * -> *) a.
(MonadTCEnv tcm, ReadTCState tcm) =>
tcm a -> tcm a
inTopContext (TCMT IO Doc -> TCMT IO Doc) -> TCMT IO Doc -> TCMT IO Doc
forall a b. (a -> b) -> a -> b
$ b -> TCMT IO Doc -> TCMT IO Doc
forall b (m :: * -> *) a.
(AddContext b, MonadAddContext m) =>
b -> m a -> m a
forall (m :: * -> *) a. MonadAddContext m => b -> m a -> m a
addContext b
tel (TCMT IO Doc -> TCMT IO Doc) -> TCMT IO Doc -> TCMT IO Doc
forall a b. (a -> b) -> a -> b
$ Int -> TCMT IO Doc -> TCMT IO Doc
forall (m :: * -> *). Functor m => Int -> m Doc -> m Doc
nest Int
2 (TCMT IO Doc -> TCMT IO Doc) -> TCMT IO Doc -> TCMT IO Doc
forall a b. (a -> b) -> a -> b
$ [TCMT IO Doc] -> TCMT IO Doc
forall (m :: * -> *) (t :: * -> *).
(Applicative m, Foldable t) =>
t (m Doc) -> m Doc
vcat
          [ TCMT IO Doc
"ps     =" TCMT IO Doc -> TCMT IO Doc -> TCMT IO Doc
forall (m :: * -> *). Applicative m => m Doc -> m Doc -> m Doc
<+> NAPs -> TCMT IO Doc
forall (m :: * -> *). MonadPretty m => NAPs -> m Doc
prettyTCMPatternList ([NamedArg SplitPattern] -> NAPs
fromSplitPatterns [NamedArg SplitPattern]
ps)
          ]

    debugPlugged :: b -> [NamedArg SplitPattern] -> tcm ()
debugPlugged b
delta' [NamedArg SplitPattern]
ps' = do
      TCMT IO () -> tcm ()
forall a. TCM a -> tcm a
forall (tcm :: * -> *) a. MonadTCM tcm => TCM a -> tcm a
liftTCM (TCMT IO () -> tcm ()) -> TCMT IO () -> tcm ()
forall a b. (a -> b) -> a -> b
$ [Char] -> Int -> TCMT IO Doc -> TCMT IO ()
forall (m :: * -> *).
MonadDebug m =>
[Char] -> Int -> TCMT IO Doc -> m ()
reportSDoc [Char]
"tc.cover.split.con" Int
20 (TCMT IO Doc -> TCMT IO ()) -> TCMT IO Doc -> TCMT IO ()
forall a b. (a -> b) -> a -> b
$
        TCMT IO Doc -> TCMT IO Doc
forall (tcm :: * -> *) a.
(MonadTCEnv tcm, ReadTCState tcm) =>
tcm a -> tcm a
inTopContext (TCMT IO Doc -> TCMT IO Doc) -> TCMT IO Doc -> TCMT IO Doc
forall a b. (a -> b) -> a -> b
$ b -> TCMT IO Doc -> TCMT IO Doc
forall b (m :: * -> *) a.
(AddContext b, MonadAddContext m) =>
b -> m a -> m a
forall (m :: * -> *) a. MonadAddContext m => b -> m a -> m a
addContext b
delta' (TCMT IO Doc -> TCMT IO Doc) -> TCMT IO Doc -> TCMT IO Doc
forall a b. (a -> b) -> a -> b
$ Int -> TCMT IO Doc -> TCMT IO Doc
forall (m :: * -> *). Functor m => Int -> m Doc -> m Doc
nest Int
2 (TCMT IO Doc -> TCMT IO Doc) -> TCMT IO Doc -> TCMT IO Doc
forall a b. (a -> b) -> a -> b
$ [TCMT IO Doc] -> TCMT IO Doc
forall (m :: * -> *) (t :: * -> *).
(Applicative m, Foldable t) =>
t (m Doc) -> m Doc
vcat
          [ TCMT IO Doc
"ps'    =" TCMT IO Doc -> TCMT IO Doc -> TCMT IO Doc
forall (m :: * -> *). Applicative m => m Doc -> m Doc -> m Doc
<+> do NAPs -> TCMT IO Doc
forall (m :: * -> *). MonadPretty m => NAPs -> m Doc
prettyTCMPatternList (NAPs -> TCMT IO Doc) -> NAPs -> TCMT IO Doc
forall a b. (a -> b) -> a -> b
$ [NamedArg SplitPattern] -> NAPs
fromSplitPatterns [NamedArg SplitPattern]
ps'
          ]

-- | Introduce trailing pattern variables?
data InsertTrailing
  = DoInsertTrailing
  | DontInsertTrailing
  deriving (InsertTrailing -> InsertTrailing -> Bool
(InsertTrailing -> InsertTrailing -> Bool)
-> (InsertTrailing -> InsertTrailing -> Bool) -> Eq InsertTrailing
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: InsertTrailing -> InsertTrailing -> Bool
== :: InsertTrailing -> InsertTrailing -> Bool
$c/= :: InsertTrailing -> InsertTrailing -> Bool
/= :: InsertTrailing -> InsertTrailing -> Bool
Eq, Int -> InsertTrailing -> [Char] -> [Char]
[InsertTrailing] -> [Char] -> [Char]
InsertTrailing -> [Char]
(Int -> InsertTrailing -> [Char] -> [Char])
-> (InsertTrailing -> [Char])
-> ([InsertTrailing] -> [Char] -> [Char])
-> Show InsertTrailing
forall a.
(Int -> a -> [Char] -> [Char])
-> (a -> [Char]) -> ([a] -> [Char] -> [Char]) -> Show a
$cshowsPrec :: Int -> InsertTrailing -> [Char] -> [Char]
showsPrec :: Int -> InsertTrailing -> [Char] -> [Char]
$cshow :: InsertTrailing -> [Char]
show :: InsertTrailing -> [Char]
$cshowList :: [InsertTrailing] -> [Char] -> [Char]
showList :: [InsertTrailing] -> [Char] -> [Char]
Show)

-- | Allow partial covering for split?
data AllowPartialCover
  = YesAllowPartialCover  -- To try to coverage-check incomplete splits.
  | NoAllowPartialCover   -- Default.
  deriving (AllowPartialCover -> AllowPartialCover -> Bool
(AllowPartialCover -> AllowPartialCover -> Bool)
-> (AllowPartialCover -> AllowPartialCover -> Bool)
-> Eq AllowPartialCover
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: AllowPartialCover -> AllowPartialCover -> Bool
== :: AllowPartialCover -> AllowPartialCover -> Bool
$c/= :: AllowPartialCover -> AllowPartialCover -> Bool
/= :: AllowPartialCover -> AllowPartialCover -> Bool
Eq, Int -> AllowPartialCover -> [Char] -> [Char]
[AllowPartialCover] -> [Char] -> [Char]
AllowPartialCover -> [Char]
(Int -> AllowPartialCover -> [Char] -> [Char])
-> (AllowPartialCover -> [Char])
-> ([AllowPartialCover] -> [Char] -> [Char])
-> Show AllowPartialCover
forall a.
(Int -> a -> [Char] -> [Char])
-> (a -> [Char]) -> ([a] -> [Char] -> [Char]) -> Show a
$cshowsPrec :: Int -> AllowPartialCover -> [Char] -> [Char]
showsPrec :: Int -> AllowPartialCover -> [Char] -> [Char]
$cshow :: AllowPartialCover -> [Char]
show :: AllowPartialCover -> [Char]
$cshowList :: [AllowPartialCover] -> [Char] -> [Char]
showList :: [AllowPartialCover] -> [Char] -> [Char]
Show)

-- | Entry point from @Interaction.MakeCase@.
splitClauseWithAbsurd :: SplitClause -> Nat -> TCM (Either SplitError (Either SplitClause Covering))
splitClauseWithAbsurd :: SplitClause
-> Int -> TCM (Either SplitError (Either SplitClause Covering))
splitClauseWithAbsurd SplitClause
c Int
x =
  CheckEmpty
-> Induction
-> AllowPartialCover
-> InsertTrailing
-> SplitClause
-> BlockingVar
-> TCM (Either SplitError (Either SplitClause Covering))
split' CheckEmpty
CheckEmpty Induction
Inductive AllowPartialCover
NoAllowPartialCover InsertTrailing
DontInsertTrailing SplitClause
c (Int -> [ConHead] -> [Literal] -> Bool -> Bool -> BlockingVar
BlockingVar Int
x [] [] Bool
True Bool
False)
  -- Andreas, 2016-05-03, issue 1950:
  -- Do not introduce trailing pattern vars after split,
  -- because this does not work for with-clauses.

-- | Entry point from @TypeChecking.Empty@ and @Interaction.BasicOps@.
--   @splitLast CoInductive@ is used in the @refine@ tactics.

splitLast :: Induction -> Telescope -> [NamedArg DeBruijnPattern] -> TCM (Either SplitError Covering)
splitLast :: Induction
-> Telescope -> NAPs -> TCMT IO (Either SplitError Covering)
splitLast Induction
ind Telescope
tel NAPs
ps = Induction
-> AllowPartialCover
-> SplitClause
-> BlockingVar
-> TCMT IO (Either SplitError Covering)
split Induction
ind AllowPartialCover
NoAllowPartialCover SplitClause
sc (Int -> [ConHead] -> [Literal] -> Bool -> Bool -> BlockingVar
BlockingVar Int
0 [] [] Bool
True Bool
False)
  where sc :: SplitClause
sc = Telescope
-> [NamedArg SplitPattern]
-> Substitution' SplitPattern
-> Map CheckpointId (Substitution' Term)
-> Maybe (Dom Type)
-> SplitClause
SClause Telescope
tel (NAPs -> [NamedArg SplitPattern]
toSplitPatterns NAPs
ps) Substitution' SplitPattern
forall a. Null a => a
empty Map CheckpointId (Substitution' Term)
forall a. Null a => a
empty Maybe (Dom Type)
forall {t}. Maybe (Dom (Type'' t Term))
target
        -- TODO 2ltt: allows (Empty_fib -> Empty_strict) which is not conservative
        target :: Maybe (Dom (Type'' t Term))
target = (Dom (Type'' t Term) -> Maybe (Dom (Type'' t Term))
forall a. a -> Maybe a
Just (Dom (Type'' t Term) -> Maybe (Dom (Type'' t Term)))
-> Dom (Type'' t Term) -> Maybe (Dom (Type'' t Term))
forall a b. (a -> b) -> a -> b
$ Type'' t Term -> Dom (Type'' t Term)
forall a. a -> Dom a
defaultDom (Type'' t Term -> Dom (Type'' t Term))
-> Type'' t Term -> Dom (Type'' t Term)
forall a b. (a -> b) -> a -> b
$ Sort' t -> Term -> Type'' t Term
forall t a. Sort' t -> a -> Type'' t a
El (Level' t -> Sort' t
forall t. Level' t -> Sort' t
Prop (Integer -> [PlusLevel' t] -> Level' t
forall t. Integer -> [PlusLevel' t] -> Level' t
Max Integer
0 [])) (Term -> Type'' t Term) -> Term -> Type'' t Term
forall a b. (a -> b) -> a -> b
$ [Char] -> Elims -> Term
Dummy [Char]
"splitLastTarget" [])

-- | @split ind splitClause x = return res@
--   splits @splitClause@ at pattern var @x@ (de Bruijn index).
--
--   Possible results @res@ are:
--
--   1. @Left err@:
--      Splitting failed.
--
--   2. @Right covering@:
--      A covering set of split clauses, one for each valid constructor.
--      This could be the empty set (denoting an absurd clause).

split :: Induction
         -- ^ Coinductive constructors are allowed if this argument is
         -- 'CoInductive'.
      -> AllowPartialCover
         -- ^ Don't fail if computed 'Covering' does not cover all constructors.
      -> SplitClause
      -> BlockingVar
      -> TCM (Either SplitError Covering)
split :: Induction
-> AllowPartialCover
-> SplitClause
-> BlockingVar
-> TCMT IO (Either SplitError Covering)
split Induction
ind AllowPartialCover
allowPartialCover SplitClause
sc BlockingVar
x =
  (Either SplitClause Covering -> Covering)
-> Either SplitError (Either SplitClause Covering)
-> Either SplitError Covering
forall a b. (a -> b) -> Either SplitError a -> Either SplitError b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Either SplitClause Covering -> Covering
blendInAbsurdClause (Either SplitError (Either SplitClause Covering)
 -> Either SplitError Covering)
-> TCM (Either SplitError (Either SplitClause Covering))
-> TCMT IO (Either SplitError Covering)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> CheckEmpty
-> Induction
-> AllowPartialCover
-> InsertTrailing
-> SplitClause
-> BlockingVar
-> TCM (Either SplitError (Either SplitClause Covering))
split' CheckEmpty
NoCheckEmpty Induction
ind AllowPartialCover
allowPartialCover InsertTrailing
DoInsertTrailing SplitClause
sc BlockingVar
x
  where
    n :: Arg Int
n = SplitClause -> Int -> Arg Int
lookupPatternVar SplitClause
sc (Int -> Arg Int) -> Int -> Arg Int
forall a b. (a -> b) -> a -> b
$ BlockingVar -> Int
blockingVarNo BlockingVar
x
    blendInAbsurdClause :: Either SplitClause Covering -> Covering
    blendInAbsurdClause :: Either SplitClause Covering -> Covering
blendInAbsurdClause = (SplitClause -> Covering)
-> Either SplitClause Covering -> Covering
forall a b. (a -> b) -> Either a b -> b
fromRight (Covering -> SplitClause -> Covering
forall a b. a -> b -> a
const (Covering -> SplitClause -> Covering)
-> Covering -> SplitClause -> Covering
forall a b. (a -> b) -> a -> b
$ Arg Int -> [(SplitTag, (SplitClause, IInfo))] -> Covering
Covering Arg Int
n [])

-- | Convert a de Bruijn index relative to the clause telescope to a de Bruijn
--   level. The result should be the argument position (counted from left,
--   starting with 0) to split at (dot patterns included!).
lookupPatternVar :: SplitClause -> Int -> Arg Nat
lookupPatternVar :: SplitClause -> Int -> Arg Int
lookupPatternVar SClause{ scTel :: SplitClause -> Telescope
scTel = Telescope
tel, scPats :: SplitClause -> [NamedArg SplitPattern]
scPats = [NamedArg SplitPattern]
pats } Int
x = Arg DeBruijnPattern
arg Arg DeBruijnPattern -> Int -> Arg Int
forall (f :: * -> *) a b. Functor f => f a -> b -> f b
$>
    if Int
n Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
0 then Int
forall a. HasCallStack => a
__IMPOSSIBLE__ else Int
n
  where n :: Int
n = if Int
k Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
0
            then Int
forall a. HasCallStack => a
__IMPOSSIBLE__
            else Int -> Maybe Int -> Int
forall a. a -> Maybe a -> a
fromMaybe Int
forall a. HasCallStack => a
__IMPOSSIBLE__ (Maybe Int -> Int) -> Maybe Int -> Int
forall a b. (a -> b) -> a -> b
$ Permutation -> [Int]
permPicks Permutation
perm [Int] -> Int -> Maybe Int
forall a. [a] -> Int -> Maybe a
!!! Int
k
        perm :: Permutation
perm = Permutation -> Maybe Permutation -> Permutation
forall a. a -> Maybe a -> a
fromMaybe Permutation
forall a. HasCallStack => a
__IMPOSSIBLE__ (Maybe Permutation -> Permutation)
-> Maybe Permutation -> Permutation
forall a b. (a -> b) -> a -> b
$ NAPs -> Maybe Permutation
dbPatPerm (NAPs -> Maybe Permutation) -> NAPs -> Maybe Permutation
forall a b. (a -> b) -> a -> b
$ [NamedArg SplitPattern] -> NAPs
fromSplitPatterns [NamedArg SplitPattern]
pats
        k :: Int
k = Telescope -> Int
forall a. Sized a => a -> Int
size Telescope
tel Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
x Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1
        arg :: Arg DeBruijnPattern
arg = Arg DeBruijnPattern
-> [Arg DeBruijnPattern] -> Int -> Arg DeBruijnPattern
forall a. a -> [a] -> Int -> a
indexWithDefault Arg DeBruijnPattern
forall a. HasCallStack => a
__IMPOSSIBLE__ (Int -> Telescope -> [Arg DeBruijnPattern]
telVars (Telescope -> Int
forall a. Sized a => a -> Int
size Telescope
tel) Telescope
tel) Int
k


data CheckEmpty = CheckEmpty | NoCheckEmpty

-- | @split' ind pc ft splitClause x = return res@
--   splits @splitClause@ at pattern var @x@ (de Bruijn index).
--
--   Possible results @res@ are:
--
--   1. @Left err@:
--      Splitting failed.
--
--   2. @Right (Left splitClause')@:
--      Absurd clause (type of @x@ has 0 valid constructors).
--
--   3. @Right (Right covering)@:
--      A covering set of split clauses, one for each valid constructor.

split' :: CheckEmpty
          -- ^ Use isEmptyType to check whether the type of the variable to
          -- split on is empty. This switch is necessary to break the cycle
          -- between split' and isEmptyType.
       -> Induction
          -- ^ Coinductive constructors are allowed if this argument is
          -- 'CoInductive'.
       -> AllowPartialCover
          -- ^ Don't fail if computed 'Covering' does not cover all constructors.
       -> InsertTrailing
          -- ^ If 'DoInsertTrailing', introduce new trailing variable patterns.
       -> SplitClause
       -> BlockingVar
       -> TCM (Either SplitError (Either SplitClause Covering))
split' :: CheckEmpty
-> Induction
-> AllowPartialCover
-> InsertTrailing
-> SplitClause
-> BlockingVar
-> TCM (Either SplitError (Either SplitClause Covering))
split' CheckEmpty
checkEmpty Induction
ind AllowPartialCover
allowPartialCover InsertTrailing
inserttrailing
       sc :: SplitClause
sc@(SClause Telescope
tel [NamedArg SplitPattern]
ps Substitution' SplitPattern
_ Map CheckpointId (Substitution' Term)
cps Maybe (Dom Type)
target) (BlockingVar Int
x [ConHead]
pcons' [Literal]
plits Bool
overlap Bool
lazy) =
 TCM (Either SplitError (Either SplitClause Covering))
-> TCM (Either SplitError (Either SplitClause Covering))
forall a. TCM a -> TCM a
forall (tcm :: * -> *) a. MonadTCM tcm => TCM a -> tcm a
liftTCM (TCM (Either SplitError (Either SplitClause Covering))
 -> TCM (Either SplitError (Either SplitClause Covering)))
-> TCM (Either SplitError (Either SplitClause Covering))
-> TCM (Either SplitError (Either SplitClause Covering))
forall a b. (a -> b) -> a -> b
$ ExceptT SplitError (TCMT IO) (Either SplitClause Covering)
-> TCM (Either SplitError (Either SplitClause Covering))
forall e (m :: * -> *) a. ExceptT e m a -> m (Either e a)
runExceptT (ExceptT SplitError (TCMT IO) (Either SplitClause Covering)
 -> TCM (Either SplitError (Either SplitClause Covering)))
-> ExceptT SplitError (TCMT IO) (Either SplitClause Covering)
-> TCM (Either SplitError (Either SplitClause Covering))
forall a b. (a -> b) -> a -> b
$ do
  Telescope
-> Int
-> [NamedArg SplitPattern]
-> Map CheckpointId (Substitution' Term)
-> ExceptT SplitError (TCMT IO) ()
forall {tcm :: * -> *} {a} {a} {a}.
(MonadTCM tcm, AddContext a, PrettyTCM a, PrettyTCM a, PrettyTCM a,
 Show a, Show a, Show a) =>
a -> a -> [NamedArg SplitPattern] -> a -> tcm ()
debugInit Telescope
tel Int
x [NamedArg SplitPattern]
ps Map CheckpointId (Substitution' Term)
cps

  -- Split the telescope at the variable
  -- t = type of the variable,  Δ₁ ⊢ t
  (n, t, delta1, delta2) <- do
    let (ListTel
tel1, Dom ([Char], Type)
dom : ListTel
tel2) = Int -> ListTel -> (ListTel, ListTel)
forall a. Int -> [a] -> ([a], [a])
splitAt (Telescope -> Int
forall a. Sized a => a -> Int
size Telescope
tel Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
x Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1) (ListTel -> (ListTel, ListTel)) -> ListTel -> (ListTel, ListTel)
forall a b. (a -> b) -> a -> b
$ Telescope -> ListTel
forall t. Tele (Dom t) -> [Dom ([Char], t)]
telToList Telescope
tel
    ([Char], Dom Type, Telescope, Telescope)
-> ExceptT
     SplitError (TCMT IO) ([Char], Dom Type, Telescope, Telescope)
forall a. a -> ExceptT SplitError (TCMT IO) a
forall (m :: * -> *) a. Monad m => a -> m a
return (([Char], Type) -> [Char]
forall a b. (a, b) -> a
fst (([Char], Type) -> [Char]) -> ([Char], Type) -> [Char]
forall a b. (a -> b) -> a -> b
$ Dom ([Char], Type) -> ([Char], Type)
forall t e. Dom' t e -> e
unDom Dom ([Char], Type)
dom, ([Char], Type) -> Type
forall a b. (a, b) -> b
snd (([Char], Type) -> Type) -> Dom ([Char], Type) -> Dom Type
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Dom ([Char], Type)
dom, ListTel -> Telescope
telFromList ListTel
tel1, ListTel -> Telescope
telFromList ListTel
tel2)

  -- Compute the neighbourhoods for the constructors
  let computeNeighborhoods = do
        -- Check that t is a datatype or a record
        -- Andreas, 2010-09-21, isDatatype now directly throws an exception if it fails
        -- cons = constructors of this datatype
        (dr, d, pars, ixs, cons', isHIT) <- ExceptT
  SplitError
  (TCMT IO)
  (DataOrRecord, QName, Args, Args, [QName], Bool)
-> ExceptT
     SplitError
     (TCMT IO)
     (DataOrRecord, QName, Args, Args, [QName], Bool)
forall (tcm :: * -> *) a.
(MonadTCM tcm, MonadAddContext tcm, MonadDebug tcm) =>
tcm a -> tcm a
inContextOfT (ExceptT
   SplitError
   (TCMT IO)
   (DataOrRecord, QName, Args, Args, [QName], Bool)
 -> ExceptT
      SplitError
      (TCMT IO)
      (DataOrRecord, QName, Args, Args, [QName], Bool))
-> ExceptT
     SplitError
     (TCMT IO)
     (DataOrRecord, QName, Args, Args, [QName], Bool)
-> ExceptT
     SplitError
     (TCMT IO)
     (DataOrRecord, QName, Args, Args, [QName], Bool)
forall a b. (a -> b) -> a -> b
$ Induction
-> Dom Type
-> ExceptT
     SplitError
     (TCMT IO)
     (DataOrRecord, QName, Args, Args, [QName], Bool)
forall (tcm :: * -> *).
(MonadTCM tcm, MonadError SplitError tcm) =>
Induction
-> Dom Type -> tcm (DataOrRecord, QName, Args, Args, [QName], Bool)
isDatatype Induction
ind Dom Type
t
        isFib <- lift $ isFibrant t
        cons <- case checkEmpty of
          CheckEmpty
CheckEmpty   -> ExceptT SplitError (TCMT IO) Bool
-> ExceptT SplitError (TCMT IO) [QName]
-> ExceptT SplitError (TCMT IO) [QName]
-> ExceptT SplitError (TCMT IO) [QName]
forall (m :: * -> *) a. Monad m => m Bool -> m a -> m a -> m a
ifM (TCMT IO Bool -> ExceptT SplitError (TCMT IO) Bool
forall a. TCM a -> ExceptT SplitError (TCMT IO) a
forall (tcm :: * -> *) a. MonadTCM tcm => TCM a -> tcm a
liftTCM (TCMT IO Bool -> ExceptT SplitError (TCMT IO) Bool)
-> TCMT IO Bool -> ExceptT SplitError (TCMT IO) Bool
forall a b. (a -> b) -> a -> b
$ TCMT IO Bool -> TCMT IO Bool
forall (tcm :: * -> *) a.
(MonadTCM tcm, MonadAddContext tcm, MonadDebug tcm) =>
tcm a -> tcm a
inContextOfT (TCMT IO Bool -> TCMT IO Bool) -> TCMT IO Bool -> TCMT IO Bool
forall a b. (a -> b) -> a -> b
$ Type -> TCMT IO Bool
isEmptyType (Type -> TCMT IO Bool) -> Type -> TCMT IO Bool
forall a b. (a -> b) -> a -> b
$ Dom Type -> Type
forall t e. Dom' t e -> e
unDom Dom Type
t) ([QName] -> ExceptT SplitError (TCMT IO) [QName]
forall a. a -> ExceptT SplitError (TCMT IO) a
forall (f :: * -> *) a. Applicative f => a -> f a
pure []) ([QName] -> ExceptT SplitError (TCMT IO) [QName]
forall a. a -> ExceptT SplitError (TCMT IO) a
forall (f :: * -> *) a. Applicative f => a -> f a
pure [QName]
cons')
          CheckEmpty
NoCheckEmpty -> [QName] -> ExceptT SplitError (TCMT IO) [QName]
forall a. a -> ExceptT SplitError (TCMT IO) a
forall (f :: * -> *) a. Applicative f => a -> f a
pure [QName]
cons'
        mns  <- forM cons $ \ QName
con -> ((SplitClause, IInfo) -> (SplitTag, (SplitClause, IInfo)))
-> Maybe (SplitClause, IInfo)
-> Maybe (SplitTag, (SplitClause, IInfo))
forall a b. (a -> b) -> Maybe a -> Maybe b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (QName -> SplitTag
SplitCon QName
con,) (Maybe (SplitClause, IInfo)
 -> Maybe (SplitTag, (SplitClause, IInfo)))
-> CoverM (Maybe (SplitClause, IInfo))
-> ExceptT
     SplitError (TCMT IO) (Maybe (SplitTag, (SplitClause, IInfo)))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$>
          Telescope
-> [Char]
-> Telescope
-> QName
-> Args
-> Args
-> Int
-> Telescope
-> [NamedArg SplitPattern]
-> Map CheckpointId (Substitution' Term)
-> QName
-> CoverM (Maybe (SplitClause, IInfo))
computeNeighbourhood Telescope
delta1 [Char]
n Telescope
delta2 QName
d Args
pars Args
ixs Int
x Telescope
tel [NamedArg SplitPattern]
ps Map CheckpointId (Substitution' Term)
cps QName
con
        hcompsc <- if isFib && (isHIT || not (null ixs)) && not (null mns) && inserttrailing == DoInsertTrailing
                   then computeHCompSplit delta1 n delta2 d pars ixs x tel ps cps
                   else return Nothing
        let ns = [Maybe (SplitTag, (SplitClause, IInfo))]
-> [(SplitTag, (SplitClause, IInfo))]
forall a. [Maybe a] -> [a]
catMaybes [Maybe (SplitTag, (SplitClause, IInfo))]
mns
        return ( dr
               , not (null ixs) -- Is "d" indexed?
               , length $ ns
               , ns ++ catMaybes ([fmap (fmap (,NoInfo)) hcompsc | not $ null $ ns])
               )

      computeLitNeighborhoods = do
        typeOk <- TCMT IO Bool -> ExceptT SplitError (TCMT IO) Bool
forall a. TCM a -> ExceptT SplitError (TCMT IO) a
forall (tcm :: * -> *) a. MonadTCM tcm => TCM a -> tcm a
liftTCM (TCMT IO Bool -> ExceptT SplitError (TCMT IO) Bool)
-> TCMT IO Bool -> ExceptT SplitError (TCMT IO) Bool
forall a b. (a -> b) -> a -> b
$ do
          t' <- Literal -> TCM Type
forall (m :: * -> *).
(HasBuiltins m, MonadError TCErr m, MonadTCEnv m, ReadTCState m) =>
Literal -> m Type
litType (Literal -> TCM Type) -> Literal -> TCM Type
forall a b. (a -> b) -> a -> b
$ Literal -> [Literal] -> Literal
forall a. a -> [a] -> a
headWithDefault {-'-} Literal
forall a. HasCallStack => a
__IMPOSSIBLE__ [Literal]
plits
          liftTCM $ dontAssignMetas $ tryConversion $ equalType (unDom t) t'
        unless typeOk $ throwError . NotADatatype =<< do liftTCM $ buildClosure (unDom t)
        ns <- forM plits $ \Literal
lit -> do
          let delta2' :: Telescope
delta2' = Int -> SubstArg Telescope -> Telescope -> Telescope
forall a. Subst a => Int -> SubstArg a -> a -> a
subst Int
0 (Literal -> Term
Lit Literal
lit) Telescope
delta2
              delta' :: Telescope
delta'  = Telescope
delta1 Telescope -> Telescope -> Telescope
forall t. Abstract t => Telescope -> t -> t
`abstract` Telescope
delta2'
              rho :: Substitution' SplitPattern
rho     = Int -> Substitution' SplitPattern -> Substitution' SplitPattern
forall a. Int -> Substitution' a -> Substitution' a
liftS Int
x (Substitution' SplitPattern -> Substitution' SplitPattern)
-> Substitution' SplitPattern -> Substitution' SplitPattern
forall a b. (a -> b) -> a -> b
$ SplitPattern
-> Substitution' SplitPattern -> Substitution' SplitPattern
forall a. DeBruijn a => a -> Substitution' a -> Substitution' a
consS (Literal -> SplitPattern
forall a. Literal -> Pattern' a
litP Literal
lit) Substitution' SplitPattern
forall a. Substitution' a
idS
              ps' :: [NamedArg SplitPattern]
ps'     = Substitution' (SubstArg [NamedArg SplitPattern])
-> [NamedArg SplitPattern] -> [NamedArg SplitPattern]
forall a. Subst a => Substitution' (SubstArg a) -> a -> a
applySubst Substitution' SplitPattern
Substitution' (SubstArg [NamedArg SplitPattern])
rho [NamedArg SplitPattern]
ps
              cps' :: Map CheckpointId (Substitution' Term)
cps'    = Substitution' SplitPattern
-> Map CheckpointId (Substitution' Term)
-> Map CheckpointId (Substitution' Term)
forall a. TermSubst a => Substitution' SplitPattern -> a -> a
applySplitPSubst Substitution' SplitPattern
rho Map CheckpointId (Substitution' Term)
cps
          (SplitTag, SplitClause)
-> ExceptT SplitError (TCMT IO) (SplitTag, SplitClause)
forall a. a -> ExceptT SplitError (TCMT IO) a
forall (m :: * -> *) a. Monad m => a -> m a
return (Literal -> SplitTag
SplitLit Literal
lit , Telescope
-> [NamedArg SplitPattern]
-> Substitution' SplitPattern
-> Map CheckpointId (Substitution' Term)
-> Maybe (Dom Type)
-> SplitClause
SClause Telescope
delta' [NamedArg SplitPattern]
ps' Substitution' SplitPattern
rho Map CheckpointId (Substitution' Term)
cps' Maybe (Dom Type)
forall a. Maybe a
Nothing)
        ca <- do
          let delta' = Telescope
tel -- telescope is unchanged for catchall branch
              varp   = PatternInfo -> SplitPatVar -> SplitPattern
forall x. PatternInfo -> x -> Pattern' x
VarP (PatOrigin -> [Name] -> PatternInfo
PatternInfo PatOrigin
PatOSplit []) (SplitPatVar -> SplitPattern) -> SplitPatVar -> SplitPattern
forall a b. (a -> b) -> a -> b
$ SplitPatVar
                         { splitPatVarName :: [Char]
splitPatVarName   = [Char]
forall a. Underscore a => a
underscore
                         , splitPatVarIndex :: Int
splitPatVarIndex  = Int
0
                         , splitExcludedLits :: [Literal]
splitExcludedLits = [Literal]
plits
                         }
              rho    = Int -> Substitution' SplitPattern -> Substitution' SplitPattern
forall a. Int -> Substitution' a -> Substitution' a
liftS Int
x (Substitution' SplitPattern -> Substitution' SplitPattern)
-> Substitution' SplitPattern -> Substitution' SplitPattern
forall a b. (a -> b) -> a -> b
$ SplitPattern
-> Substitution' SplitPattern -> Substitution' SplitPattern
forall a. DeBruijn a => a -> Substitution' a -> Substitution' a
consS SplitPattern
varp (Substitution' SplitPattern -> Substitution' SplitPattern)
-> Substitution' SplitPattern -> Substitution' SplitPattern
forall a b. (a -> b) -> a -> b
$ Int -> Substitution' SplitPattern
forall a. Int -> Substitution' a
raiseS Int
1
              ps'    = Substitution' (SubstArg [NamedArg SplitPattern])
-> [NamedArg SplitPattern] -> [NamedArg SplitPattern]
forall a. Subst a => Substitution' (SubstArg a) -> a -> a
applySubst Substitution' SplitPattern
Substitution' (SubstArg [NamedArg SplitPattern])
rho [NamedArg SplitPattern]
ps
          return (SplitCatchall , SClause delta' ps' rho cps Nothing)

        -- If Agda is changed so that the type of a literal can belong
        -- to an inductive family (with at least one index), then the
        -- following code should be changed (the constructor False
        -- stands for "not indexed").
        let ns' = ((SplitTag, SplitClause) -> (SplitTag, (SplitClause, IInfo)))
-> [(SplitTag, SplitClause)] -> [(SplitTag, (SplitClause, IInfo))]
forall a b. (a -> b) -> [a] -> [b]
map (((SplitClause -> (SplitClause, IInfo))
-> (SplitTag, SplitClause) -> (SplitTag, (SplitClause, IInfo))
forall a b. (a -> b) -> (SplitTag, a) -> (SplitTag, b)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (,IInfo
NoInfo))) ([(SplitTag, SplitClause)] -> [(SplitTag, (SplitClause, IInfo))])
-> [(SplitTag, SplitClause)] -> [(SplitTag, (SplitClause, IInfo))]
forall a b. (a -> b) -> a -> b
$ [(SplitTag, SplitClause)]
ns [(SplitTag, SplitClause)]
-> [(SplitTag, SplitClause)] -> [(SplitTag, SplitClause)]
forall a. [a] -> [a] -> [a]
++ [ (SplitTag, SplitClause)
ca ]
        return (IsData, False, length ns', ns')

  -- numMatching is the number of proper constructors matching, excluding hcomp.
  -- for literals this considers the catchall clause as 1 extra constructor.
  (dr, isIndexed, numMatching, ns) <- if null pcons' && not (null plits)
        then computeLitNeighborhoods
        else computeNeighborhoods

  ns <- case target of
    Just Dom Type
a  -> [(SplitTag, (SplitClause, IInfo))]
-> ((SplitTag, (SplitClause, IInfo))
    -> ExceptT SplitError (TCMT IO) (SplitTag, (SplitClause, IInfo)))
-> ExceptT SplitError (TCMT IO) [(SplitTag, (SplitClause, IInfo))]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
t a -> (a -> m b) -> m (t b)
forM [(SplitTag, (SplitClause, IInfo))]
ns (((SplitTag, (SplitClause, IInfo))
  -> ExceptT SplitError (TCMT IO) (SplitTag, (SplitClause, IInfo)))
 -> ExceptT SplitError (TCMT IO) [(SplitTag, (SplitClause, IInfo))])
-> ((SplitTag, (SplitClause, IInfo))
    -> ExceptT SplitError (TCMT IO) (SplitTag, (SplitClause, IInfo)))
-> ExceptT SplitError (TCMT IO) [(SplitTag, (SplitClause, IInfo))]
forall a b. (a -> b) -> a -> b
$ \ (SplitTag
con,(SplitClause
sc,IInfo
info)) -> TCMT IO (SplitTag, (SplitClause, IInfo))
-> ExceptT SplitError (TCMT IO) (SplitTag, (SplitClause, IInfo))
forall (m :: * -> *) a. Monad m => m a -> ExceptT SplitError m a
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (TCMT IO (SplitTag, (SplitClause, IInfo))
 -> ExceptT SplitError (TCMT IO) (SplitTag, (SplitClause, IInfo)))
-> TCMT IO (SplitTag, (SplitClause, IInfo))
-> ExceptT SplitError (TCMT IO) (SplitTag, (SplitClause, IInfo))
forall a b. (a -> b) -> a -> b
$ (SplitTag
con,) ((SplitClause, IInfo) -> (SplitTag, (SplitClause, IInfo)))
-> (SplitClause -> (SplitClause, IInfo))
-> SplitClause
-> (SplitTag, (SplitClause, IInfo))
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (,IInfo
info) (SplitClause -> (SplitTag, (SplitClause, IInfo)))
-> TCMT IO SplitClause -> TCMT IO (SplitTag, (SplitClause, IInfo))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$>
                 Quantity
-> SplitTag -> SplitClause -> Dom Type -> TCMT IO SplitClause
fixTargetType (Dom Type -> Quantity
forall a. LensQuantity a => a -> Quantity
getQuantity Dom Type
t) SplitTag
con SplitClause
sc Dom Type
a
    Maybe (Dom Type)
Nothing -> [(SplitTag, (SplitClause, IInfo))]
-> ExceptT SplitError (TCMT IO) [(SplitTag, (SplitClause, IInfo))]
forall a. a -> ExceptT SplitError (TCMT IO) a
forall (m :: * -> *) a. Monad m => a -> m a
return [(SplitTag, (SplitClause, IInfo))]
ns

  ns <- case inserttrailing of
    InsertTrailing
DontInsertTrailing -> [(SplitTag, (SplitClause, IInfo))]
-> ExceptT SplitError (TCMT IO) [(SplitTag, (SplitClause, IInfo))]
forall a. a -> ExceptT SplitError (TCMT IO) a
forall (m :: * -> *) a. Monad m => a -> m a
return [(SplitTag, (SplitClause, IInfo))]
ns
    InsertTrailing
DoInsertTrailing   -> TCMT IO [(SplitTag, (SplitClause, IInfo))]
-> ExceptT SplitError (TCMT IO) [(SplitTag, (SplitClause, IInfo))]
forall (m :: * -> *) a. Monad m => m a -> ExceptT SplitError m a
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (TCMT IO [(SplitTag, (SplitClause, IInfo))]
 -> ExceptT SplitError (TCMT IO) [(SplitTag, (SplitClause, IInfo))])
-> TCMT IO [(SplitTag, (SplitClause, IInfo))]
-> ExceptT SplitError (TCMT IO) [(SplitTag, (SplitClause, IInfo))]
forall a b. (a -> b) -> a -> b
$ [(SplitTag, (SplitClause, IInfo))]
-> ((SplitTag, (SplitClause, IInfo))
    -> TCMT IO (SplitTag, (SplitClause, IInfo)))
-> TCMT IO [(SplitTag, (SplitClause, IInfo))]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
t a -> (a -> m b) -> m (t b)
forM [(SplitTag, (SplitClause, IInfo))]
ns (((SplitTag, (SplitClause, IInfo))
  -> TCMT IO (SplitTag, (SplitClause, IInfo)))
 -> TCMT IO [(SplitTag, (SplitClause, IInfo))])
-> ((SplitTag, (SplitClause, IInfo))
    -> TCMT IO (SplitTag, (SplitClause, IInfo)))
-> TCMT IO [(SplitTag, (SplitClause, IInfo))]
forall a b. (a -> b) -> a -> b
$ \(SplitTag
con,(SplitClause
sc,IInfo
info)) ->
      (SplitTag
con,) ((SplitClause, IInfo) -> (SplitTag, (SplitClause, IInfo)))
-> ((Telescope, SplitClause) -> (SplitClause, IInfo))
-> (Telescope, SplitClause)
-> (SplitTag, (SplitClause, IInfo))
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (,IInfo
info) (SplitClause -> (SplitClause, IInfo))
-> ((Telescope, SplitClause) -> SplitClause)
-> (Telescope, SplitClause)
-> (SplitClause, IInfo)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Telescope, SplitClause) -> SplitClause
forall a b. (a, b) -> b
snd ((Telescope, SplitClause) -> (SplitTag, (SplitClause, IInfo)))
-> TCM (Telescope, SplitClause)
-> TCMT IO (SplitTag, (SplitClause, IInfo))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Bool -> SplitClause -> TCM (Telescope, SplitClause)
insertTrailingArgs Bool
False SplitClause
sc

  mHCompName <- getPrimitiveName' builtinHComp
  opts       <- pragmaOptions
  let withoutK        = PragmaOptions -> Bool
optWithoutK PragmaOptions
opts
      erasedMatches   = PragmaOptions -> Bool
optErasedMatches PragmaOptions
opts
      isRecordWithEta = case DataOrRecord
dr of
        DataOrRecord
IsData       -> Bool
False
        IsRecord InductionAndEta
r ->
          case EtaEquality -> HasEta
theEtaEquality (InductionAndEta -> EtaEquality
recordEtaEquality InductionAndEta
r) of
            YesEta{} -> Bool
True
            NoEta{}  -> Bool
False

  erased <- hasQuantity0 <$> viewTC eQuantity
  reportSLn "tc.cover.split" 60 $ "We are in erased context = " ++ show erased
  let erasedError ErasedDatatypeReason
reason =
        SplitError
-> ExceptT SplitError (TCMT IO) (Either SplitClause Covering)
forall a. SplitError -> ExceptT SplitError (TCMT IO) a
forall e (m :: * -> *) a. MonadError e m => e -> m a
throwError (SplitError
 -> ExceptT SplitError (TCMT IO) (Either SplitClause Covering))
-> (Closure Type -> SplitError)
-> Closure Type
-> ExceptT SplitError (TCMT IO) (Either SplitClause Covering)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ErasedDatatypeReason -> Closure Type -> SplitError
ErasedDatatype ErasedDatatypeReason
reason (Closure Type
 -> ExceptT SplitError (TCMT IO) (Either SplitClause Covering))
-> ExceptT SplitError (TCMT IO) (Closure Type)
-> ExceptT SplitError (TCMT IO) (Either SplitClause Covering)
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<<
          do TCM (Closure Type) -> ExceptT SplitError (TCMT IO) (Closure Type)
forall a. TCM a -> ExceptT SplitError (TCMT IO) a
forall (tcm :: * -> *) a. MonadTCM tcm => TCM a -> tcm a
liftTCM (TCM (Closure Type) -> ExceptT SplitError (TCMT IO) (Closure Type))
-> TCM (Closure Type)
-> ExceptT SplitError (TCMT IO) (Closure Type)
forall a b. (a -> b) -> a -> b
$ TCM (Closure Type) -> TCM (Closure Type)
forall (tcm :: * -> *) a.
(MonadTCM tcm, MonadAddContext tcm, MonadDebug tcm) =>
tcm a -> tcm a
inContextOfT (TCM (Closure Type) -> TCM (Closure Type))
-> TCM (Closure Type) -> TCM (Closure Type)
forall a b. (a -> b) -> a -> b
$ Type -> TCM (Closure Type)
forall (m :: * -> *) a.
(MonadTCEnv m, ReadTCState m) =>
a -> m (Closure a)
buildClosure (Dom Type -> Type
forall t e. Dom' t e -> e
unDom Dom Type
t)

  case numMatching of
    Int
0  -> do
      let absurdp :: SplitPattern
absurdp = PatternInfo -> SplitPatVar -> SplitPattern
forall x. PatternInfo -> x -> Pattern' x
VarP (PatOrigin -> [Name] -> PatternInfo
PatternInfo PatOrigin
PatOAbsurd []) (SplitPatVar -> SplitPattern) -> SplitPatVar -> SplitPattern
forall a b. (a -> b) -> a -> b
$ [Char] -> Int -> [Literal] -> SplitPatVar
SplitPatVar [Char]
forall a. Underscore a => a
underscore Int
0 []
          rho :: Substitution' SplitPattern
rho = Int -> Substitution' SplitPattern -> Substitution' SplitPattern
forall a. Int -> Substitution' a -> Substitution' a
liftS Int
x (Substitution' SplitPattern -> Substitution' SplitPattern)
-> Substitution' SplitPattern -> Substitution' SplitPattern
forall a b. (a -> b) -> a -> b
$ SplitPattern
-> Substitution' SplitPattern -> Substitution' SplitPattern
forall a. DeBruijn a => a -> Substitution' a -> Substitution' a
consS SplitPattern
absurdp (Substitution' SplitPattern -> Substitution' SplitPattern)
-> Substitution' SplitPattern -> Substitution' SplitPattern
forall a b. (a -> b) -> a -> b
$ Int -> Substitution' SplitPattern
forall a. Int -> Substitution' a
raiseS Int
1
          ps' :: [NamedArg SplitPattern]
ps' = Substitution' (SubstArg [NamedArg SplitPattern])
-> [NamedArg SplitPattern] -> [NamedArg SplitPattern]
forall a. Subst a => Substitution' (SubstArg a) -> a -> a
applySubst Substitution' SplitPattern
Substitution' (SubstArg [NamedArg SplitPattern])
rho [NamedArg SplitPattern]
ps
      Either SplitClause Covering
-> ExceptT SplitError (TCMT IO) (Either SplitClause Covering)
forall a. a -> ExceptT SplitError (TCMT IO) a
forall (m :: * -> *) a. Monad m => a -> m a
return (Either SplitClause Covering
 -> ExceptT SplitError (TCMT IO) (Either SplitClause Covering))
-> Either SplitClause Covering
-> ExceptT SplitError (TCMT IO) (Either SplitClause Covering)
forall a b. (a -> b) -> a -> b
$ SplitClause -> Either SplitClause Covering
forall a b. a -> Either a b
Left (SplitClause -> Either SplitClause Covering)
-> SplitClause -> Either SplitClause Covering
forall a b. (a -> b) -> a -> b
$ SClause
               { scTel :: Telescope
scTel  = Telescope
tel
               , scPats :: [NamedArg SplitPattern]
scPats = [NamedArg SplitPattern]
ps'
               , scSubst :: Substitution' SplitPattern
scSubst              = Substitution' SplitPattern
forall a. HasCallStack => a
__IMPOSSIBLE__ -- not used
               , scCheckpoints :: Map CheckpointId (Substitution' Term)
scCheckpoints        = Map CheckpointId (Substitution' Term)
forall a. HasCallStack => a
__IMPOSSIBLE__ -- not used
               , scTarget :: Maybe (Dom Type)
scTarget             = Maybe (Dom Type)
forall a. Maybe a
Nothing
               }

    -- Andreas, 2018-10-17: If more than one constructor matches, we cannot erase.
    Int
n | Int
n Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Int
1 Bool -> Bool -> Bool
&& Bool -> Bool
not Bool
erased Bool -> Bool -> Bool
&& Bool -> Bool
not (Dom Type -> Bool
forall a. LensQuantity a => a -> Bool
usableQuantity Dom Type
t) ->
      ErasedDatatypeReason
-> ExceptT SplitError (TCMT IO) (Either SplitClause Covering)
erasedError ErasedDatatypeReason
SeveralConstructors

    -- If exactly one constructor matches and the K rule is turned
    -- off, then we only allow erasure for non-indexed data/record
    -- types (#4172). If the type is not a record type with
    -- η-equality, then the flag --erased-matches must be active.
    Int
1 | Bool -> Bool
not Bool
erased Bool -> Bool -> Bool
&& Bool -> Bool
not (Dom Type -> Bool
forall a. LensQuantity a => a -> Bool
usableQuantity Dom Type
t) Bool -> Bool -> Bool
&& Bool
withoutK Bool -> Bool -> Bool
&&
        (Bool
isIndexed Bool -> Bool -> Bool
|| Bool -> Bool
not Bool
isRecordWithEta Bool -> Bool -> Bool
&& Bool -> Bool
not Bool
erasedMatches) ->
      ErasedDatatypeReason
-> ExceptT SplitError (TCMT IO) (Either SplitClause Covering)
erasedError (if Bool
isIndexed then ErasedDatatypeReason
NoK else ErasedDatatypeReason
NoErasedMatches)

    Int
_ -> do

      -- Andreas, 2012-10-10 fail if precomputed constructor set does not cover
      -- all the data type constructors
      -- Andreas, 2017-10-08 ... unless partial covering is explicitly allowed.
      let ptags :: [SplitTag]
ptags = (ConHead -> SplitTag) -> [ConHead] -> [SplitTag]
forall a b. (a -> b) -> [a] -> [b]
map (QName -> SplitTag
SplitCon (QName -> SplitTag) -> (ConHead -> QName) -> ConHead -> SplitTag
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ConHead -> QName
conName) [ConHead]
pcons' [SplitTag] -> [SplitTag] -> [SplitTag]
forall a. [a] -> [a] -> [a]
++ (Literal -> SplitTag) -> [Literal] -> [SplitTag]
forall a b. (a -> b) -> [a] -> [b]
map Literal -> SplitTag
SplitLit [Literal]
plits
      -- clauses for hcomp will be automatically generated.
      let inferred_tags :: Set SplitTag
inferred_tags = Set SplitTag
-> (QName -> Set SplitTag) -> Maybe QName -> Set SplitTag
forall b a. b -> (a -> b) -> Maybe a -> b
maybe Set SplitTag
forall a. Set a
Set.empty (SplitTag -> Set SplitTag
forall a. a -> Set a
Set.singleton (SplitTag -> Set SplitTag)
-> (QName -> SplitTag) -> QName -> Set SplitTag
forall b c a. (b -> c) -> (a -> b) -> a -> c
. QName -> SplitTag
SplitCon) Maybe QName
mHCompName
      let all_tags :: Set SplitTag
all_tags = [SplitTag] -> Set SplitTag
forall a. Ord a => [a] -> Set a
Set.fromList [SplitTag]
ptags Set SplitTag -> Set SplitTag -> Set SplitTag
forall a. Ord a => Set a -> Set a -> Set a
`Set.union` Set SplitTag
inferred_tags

      Bool
-> ExceptT SplitError (TCMT IO) ()
-> ExceptT SplitError (TCMT IO) ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (AllowPartialCover
allowPartialCover AllowPartialCover -> AllowPartialCover -> Bool
forall a. Eq a => a -> a -> Bool
== AllowPartialCover
NoAllowPartialCover Bool -> Bool -> Bool
&& Bool -> Bool
not Bool
overlap) (ExceptT SplitError (TCMT IO) ()
 -> ExceptT SplitError (TCMT IO) ())
-> ExceptT SplitError (TCMT IO) ()
-> ExceptT SplitError (TCMT IO) ()
forall a b. (a -> b) -> a -> b
$
        [(SplitTag, (SplitClause, IInfo))]
-> ((SplitTag, (SplitClause, IInfo))
    -> ExceptT SplitError (TCMT IO) ())
-> ExceptT SplitError (TCMT IO) ()
forall (t :: * -> *) (f :: * -> *) a b.
(Foldable t, Applicative f) =>
t a -> (a -> f b) -> f ()
for_ [(SplitTag, (SplitClause, IInfo))]
ns (((SplitTag, (SplitClause, IInfo))
  -> ExceptT SplitError (TCMT IO) ())
 -> ExceptT SplitError (TCMT IO) ())
-> ((SplitTag, (SplitClause, IInfo))
    -> ExceptT SplitError (TCMT IO) ())
-> ExceptT SplitError (TCMT IO) ()
forall a b. (a -> b) -> a -> b
$ \(SplitTag
tag, (SplitClause
sc, IInfo
_)) -> do
          Bool
-> ExceptT SplitError (TCMT IO) ()
-> ExceptT SplitError (TCMT IO) ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
unless (SplitTag
tag SplitTag -> Set SplitTag -> Bool
forall a. Ord a => a -> Set a -> Bool
`Set.member` Set SplitTag
all_tags) (ExceptT SplitError (TCMT IO) ()
 -> ExceptT SplitError (TCMT IO) ())
-> ExceptT SplitError (TCMT IO) ()
-> ExceptT SplitError (TCMT IO) ()
forall a b. (a -> b) -> a -> b
$ do
            isImpossibleClause <- TCMT IO Bool -> ExceptT SplitError (TCMT IO) Bool
forall a. TCM a -> ExceptT SplitError (TCMT IO) a
forall (tcm :: * -> *) a. MonadTCM tcm => TCM a -> tcm a
liftTCM (TCMT IO Bool -> ExceptT SplitError (TCMT IO) Bool)
-> TCMT IO Bool -> ExceptT SplitError (TCMT IO) Bool
forall a b. (a -> b) -> a -> b
$ Telescope -> TCMT IO Bool
isEmptyTel (Telescope -> TCMT IO Bool) -> Telescope -> TCMT IO Bool
forall a b. (a -> b) -> a -> b
$ SplitClause -> Telescope
scTel SplitClause
sc
            unless isImpossibleClause $ do
              liftTCM $ reportSDoc "tc.cover" 10 $ vcat
                [ text "Missing case for" <+> prettyTCM tag
                , nest 2 $ prettyTCM sc
                ]
              throwError (GenericSplitError "precomputed set of constructors does not cover all cases")

      TCMT IO () -> ExceptT SplitError (TCMT IO) ()
forall a. TCM a -> ExceptT SplitError (TCMT IO) a
forall (tcm :: * -> *) a. MonadTCM tcm => TCM a -> tcm a
liftTCM (TCMT IO () -> ExceptT SplitError (TCMT IO) ())
-> TCMT IO () -> ExceptT SplitError (TCMT IO) ()
forall a b. (a -> b) -> a -> b
$ TCMT IO () -> TCMT IO ()
forall (tcm :: * -> *) a.
(MonadTCM tcm, MonadAddContext tcm, MonadDebug tcm) =>
tcm a -> tcm a
inContextOfT (TCMT IO () -> TCMT IO ()) -> TCMT IO () -> TCMT IO ()
forall a b. (a -> b) -> a -> b
$ DataOrRecord -> Type -> Telescope -> Maybe (Dom Type) -> TCMT IO ()
forall (m :: * -> *) a ty.
(MonadTCM m, PureTCM m, MonadError TCErr m, LensSort a,
 PrettyTCM a, LensSort ty, PrettyTCM ty) =>
DataOrRecord -> a -> Telescope -> Maybe ty -> m ()
checkSortOfSplitVar DataOrRecord
dr (Dom Type -> Type
forall t e. Dom' t e -> e
unDom Dom Type
t) Telescope
delta2 Maybe (Dom Type)
target
      Either SplitClause Covering
-> ExceptT SplitError (TCMT IO) (Either SplitClause Covering)
forall a. a -> ExceptT SplitError (TCMT IO) a
forall (m :: * -> *) a. Monad m => a -> m a
return (Either SplitClause Covering
 -> ExceptT SplitError (TCMT IO) (Either SplitClause Covering))
-> Either SplitClause Covering
-> ExceptT SplitError (TCMT IO) (Either SplitClause Covering)
forall a b. (a -> b) -> a -> b
$ Covering -> Either SplitClause Covering
forall a b. b -> Either a b
Right (Covering -> Either SplitClause Covering)
-> Covering -> Either SplitClause Covering
forall a b. (a -> b) -> a -> b
$ Arg Int -> [(SplitTag, (SplitClause, IInfo))] -> Covering
Covering (SplitClause -> Int -> Arg Int
lookupPatternVar SplitClause
sc Int
x) [(SplitTag, (SplitClause, IInfo))]
ns

  where
    inContextOfT, inContextOfDelta2 :: (MonadTCM tcm, MonadAddContext tcm, MonadDebug tcm) => tcm a -> tcm a
    inContextOfT :: forall (tcm :: * -> *) a.
(MonadTCM tcm, MonadAddContext tcm, MonadDebug tcm) =>
tcm a -> tcm a
inContextOfT      = Telescope -> tcm a -> tcm a
forall b (m :: * -> *) a.
(AddContext b, MonadAddContext m) =>
b -> m a -> m a
forall (m :: * -> *) a.
MonadAddContext m =>
Telescope -> m a -> m a
addContext Telescope
tel (tcm a -> tcm a) -> (tcm a -> tcm a) -> tcm a -> tcm a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Impossible -> Int -> tcm a -> tcm a
forall (m :: * -> *) a.
MonadAddContext m =>
Impossible -> Int -> m a -> m a
escapeContext Impossible
HasCallStack => Impossible
impossible (Int
x Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1)
    inContextOfDelta2 :: forall (tcm :: * -> *) a.
(MonadTCM tcm, MonadAddContext tcm, MonadDebug tcm) =>
tcm a -> tcm a
inContextOfDelta2 = Telescope -> tcm a -> tcm a
forall b (m :: * -> *) a.
(AddContext b, MonadAddContext m) =>
b -> m a -> m a
forall (m :: * -> *) a.
MonadAddContext m =>
Telescope -> m a -> m a
addContext Telescope
tel (tcm a -> tcm a) -> (tcm a -> tcm a) -> tcm a -> tcm a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Impossible -> Int -> tcm a -> tcm a
forall (m :: * -> *) a.
MonadAddContext m =>
Impossible -> Int -> m a -> m a
escapeContext Impossible
HasCallStack => Impossible
impossible Int
x

    -- Debug printing
    debugInit :: a -> a -> [NamedArg SplitPattern] -> a -> tcm ()
debugInit a
tel a
x [NamedArg SplitPattern]
ps a
cps = TCMT IO () -> tcm ()
forall a. TCM a -> tcm a
forall (tcm :: * -> *) a. MonadTCM tcm => TCM a -> tcm a
liftTCM (TCMT IO () -> tcm ()) -> TCMT IO () -> tcm ()
forall a b. (a -> b) -> a -> b
$ TCMT IO () -> TCMT IO ()
forall (tcm :: * -> *) a.
(MonadTCEnv tcm, ReadTCState tcm) =>
tcm a -> tcm a
inTopContext (TCMT IO () -> TCMT IO ()) -> TCMT IO () -> TCMT IO ()
forall a b. (a -> b) -> a -> b
$ do
      [Char] -> Int -> TCMT IO Doc -> TCMT IO ()
forall (m :: * -> *).
MonadDebug m =>
[Char] -> Int -> TCMT IO Doc -> m ()
reportSDoc [Char]
"tc.cover.top" Int
10 (TCMT IO Doc -> TCMT IO ()) -> TCMT IO Doc -> TCMT IO ()
forall a b. (a -> b) -> a -> b
$ [TCMT IO Doc] -> TCMT IO Doc
forall (m :: * -> *) (t :: * -> *).
(Applicative m, Foldable t) =>
t (m Doc) -> m Doc
vcat
        [ TCMT IO Doc
"TypeChecking.Coverage.split': split"
        , Int -> TCMT IO Doc -> TCMT IO Doc
forall (m :: * -> *). Functor m => Int -> m Doc -> m Doc
nest Int
2 (TCMT IO Doc -> TCMT IO Doc) -> TCMT IO Doc -> TCMT IO Doc
forall a b. (a -> b) -> a -> b
$ [TCMT IO Doc] -> TCMT IO Doc
forall (m :: * -> *) (t :: * -> *).
(Applicative m, Foldable t) =>
t (m Doc) -> m Doc
vcat
          [ TCMT IO Doc
"tel     =" TCMT IO Doc -> TCMT IO Doc -> TCMT IO Doc
forall (m :: * -> *). Applicative m => m Doc -> m Doc -> m Doc
<+> a -> TCMT IO Doc
forall a (m :: * -> *). (PrettyTCM a, MonadPretty m) => a -> m Doc
forall (m :: * -> *). MonadPretty m => a -> m Doc
prettyTCM a
tel
          , TCMT IO Doc
"x       =" TCMT IO Doc -> TCMT IO Doc -> TCMT IO Doc
forall (m :: * -> *). Applicative m => m Doc -> m Doc -> m Doc
<+> a -> TCMT IO Doc
forall a (m :: * -> *). (PrettyTCM a, MonadPretty m) => a -> m Doc
forall (m :: * -> *). MonadPretty m => a -> m Doc
prettyTCM a
x
          , TCMT IO Doc
"ps      =" TCMT IO Doc -> TCMT IO Doc -> TCMT IO Doc
forall (m :: * -> *). Applicative m => m Doc -> m Doc -> m Doc
<+> do a -> TCMT IO Doc -> TCMT IO Doc
forall b (m :: * -> *) a.
(AddContext b, MonadAddContext m) =>
b -> m a -> m a
forall (m :: * -> *) a. MonadAddContext m => a -> m a -> m a
addContext a
tel (TCMT IO Doc -> TCMT IO Doc) -> TCMT IO Doc -> TCMT IO Doc
forall a b. (a -> b) -> a -> b
$ NAPs -> TCMT IO Doc
forall (m :: * -> *). MonadPretty m => NAPs -> m Doc
prettyTCMPatternList (NAPs -> TCMT IO Doc) -> NAPs -> TCMT IO Doc
forall a b. (a -> b) -> a -> b
$ [NamedArg SplitPattern] -> NAPs
fromSplitPatterns [NamedArg SplitPattern]
ps
          , TCMT IO Doc
"cps     =" TCMT IO Doc -> TCMT IO Doc -> TCMT IO Doc
forall (m :: * -> *). Applicative m => m Doc -> m Doc -> m Doc
<+> a -> TCMT IO Doc
forall a (m :: * -> *). (PrettyTCM a, MonadPretty m) => a -> m Doc
forall (m :: * -> *). MonadPretty m => a -> m Doc
prettyTCM a
cps
          ]
        ]
      [Char] -> Int -> TCMT IO Doc -> TCMT IO ()
forall (m :: * -> *).
MonadDebug m =>
[Char] -> Int -> TCMT IO Doc -> m ()
reportSDoc [Char]
"tc.cover.top" Int
60 (TCMT IO Doc -> TCMT IO ()) -> TCMT IO Doc -> TCMT IO ()
forall a b. (a -> b) -> a -> b
$ [TCMT IO Doc] -> TCMT IO Doc
forall (m :: * -> *) (t :: * -> *).
(Applicative m, Foldable t) =>
t (m Doc) -> m Doc
vcat
        [ TCMT IO Doc
"TypeChecking.Coverage.split': split"
        , Int -> TCMT IO Doc -> TCMT IO Doc
forall (m :: * -> *). Functor m => Int -> m Doc -> m Doc
nest Int
2 (TCMT IO Doc -> TCMT IO Doc) -> TCMT IO Doc -> TCMT IO Doc
forall a b. (a -> b) -> a -> b
$ [TCMT IO Doc] -> TCMT IO Doc
forall (m :: * -> *) (t :: * -> *).
(Applicative m, Foldable t) =>
t (m Doc) -> m Doc
vcat
          [ TCMT IO Doc
"tel     =" TCMT IO Doc -> TCMT IO Doc -> TCMT IO Doc
forall (m :: * -> *). Applicative m => m Doc -> m Doc -> m Doc
<+> ([Char] -> TCMT IO Doc
forall (m :: * -> *). Applicative m => [Char] -> m Doc
text ([Char] -> TCMT IO Doc) -> (a -> [Char]) -> a -> TCMT IO Doc
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> [Char]
forall a. Show a => a -> [Char]
show) a
tel
          , TCMT IO Doc
"x       =" TCMT IO Doc -> TCMT IO Doc -> TCMT IO Doc
forall (m :: * -> *). Applicative m => m Doc -> m Doc -> m Doc
<+> ([Char] -> TCMT IO Doc
forall (m :: * -> *). Applicative m => [Char] -> m Doc
text ([Char] -> TCMT IO Doc) -> (a -> [Char]) -> a -> TCMT IO Doc
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> [Char]
forall a. Show a => a -> [Char]
show) a
x
          , TCMT IO Doc
"ps      =" TCMT IO Doc -> TCMT IO Doc -> TCMT IO Doc
forall (m :: * -> *). Applicative m => m Doc -> m Doc -> m Doc
<+> ([Char] -> TCMT IO Doc
forall (m :: * -> *). Applicative m => [Char] -> m Doc
text ([Char] -> TCMT IO Doc)
-> ([NamedArg SplitPattern] -> [Char])
-> [NamedArg SplitPattern]
-> TCMT IO Doc
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [NamedArg SplitPattern] -> [Char]
forall a. Show a => a -> [Char]
show) [NamedArg SplitPattern]
ps
          , TCMT IO Doc
"cps     =" TCMT IO Doc -> TCMT IO Doc -> TCMT IO Doc
forall (m :: * -> *). Applicative m => m Doc -> m Doc -> m Doc
<+> ([Char] -> TCMT IO Doc
forall (m :: * -> *). Applicative m => [Char] -> m Doc
text ([Char] -> TCMT IO Doc) -> (a -> [Char]) -> a -> TCMT IO Doc
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> [Char]
forall a. Show a => a -> [Char]
show) a
cps
          ]
        ]

    debugHoleAndType :: a -> a -> [Char] -> NAPs -> a -> tcm ()
debugHoleAndType a
delta1 a
delta2 [Char]
s NAPs
ps a
t =
      TCMT IO () -> tcm ()
forall a. TCM a -> tcm a
forall (tcm :: * -> *) a. MonadTCM tcm => TCM a -> tcm a
liftTCM (TCMT IO () -> tcm ()) -> TCMT IO () -> tcm ()
forall a b. (a -> b) -> a -> b
$ [Char] -> Int -> TCMT IO Doc -> TCMT IO ()
forall (m :: * -> *).
MonadDebug m =>
[Char] -> Int -> TCMT IO Doc -> m ()
reportSDoc [Char]
"tc.cover.top" Int
10 (TCMT IO Doc -> TCMT IO ()) -> TCMT IO Doc -> TCMT IO ()
forall a b. (a -> b) -> a -> b
$ Int -> TCMT IO Doc -> TCMT IO Doc
forall (m :: * -> *). Functor m => Int -> m Doc -> m Doc
nest Int
2 (TCMT IO Doc -> TCMT IO Doc) -> TCMT IO Doc -> TCMT IO Doc
forall a b. (a -> b) -> a -> b
$ [TCMT IO Doc] -> TCMT IO Doc
forall (m :: * -> *) (t :: * -> *).
(Applicative m, Foldable t) =>
t (m Doc) -> m Doc
vcat ([TCMT IO Doc] -> TCMT IO Doc) -> [TCMT IO Doc] -> TCMT IO Doc
forall a b. (a -> b) -> a -> b
$
        [ TCMT IO Doc
"p      =" TCMT IO Doc -> TCMT IO Doc -> TCMT IO Doc
forall (m :: * -> *). Applicative m => m Doc -> m Doc -> m Doc
<+> [Char] -> TCMT IO Doc
forall (m :: * -> *). Applicative m => [Char] -> m Doc
text ([Char] -> [Char]
patVarNameToString [Char]
s)
        , TCMT IO Doc
"ps     =" TCMT IO Doc -> TCMT IO Doc -> TCMT IO Doc
forall (m :: * -> *). Applicative m => m Doc -> m Doc -> m Doc
<+> NAPs -> TCMT IO Doc
forall (m :: * -> *). MonadPretty m => NAPs -> m Doc
prettyTCMPatternList NAPs
ps
        , TCMT IO Doc
"delta1 =" TCMT IO Doc -> TCMT IO Doc -> TCMT IO Doc
forall (m :: * -> *). Applicative m => m Doc -> m Doc -> m Doc
<+> a -> TCMT IO Doc
forall a (m :: * -> *). (PrettyTCM a, MonadPretty m) => a -> m Doc
forall (m :: * -> *). MonadPretty m => a -> m Doc
prettyTCM a
delta1
        , TCMT IO Doc
"delta2 =" TCMT IO Doc -> TCMT IO Doc -> TCMT IO Doc
forall (m :: * -> *). Applicative m => m Doc -> m Doc -> m Doc
<+> TCMT IO Doc -> TCMT IO Doc
forall (tcm :: * -> *) a.
(MonadTCM tcm, MonadAddContext tcm, MonadDebug tcm) =>
tcm a -> tcm a
inContextOfDelta2 (a -> TCMT IO Doc
forall a (m :: * -> *). (PrettyTCM a, MonadPretty m) => a -> m Doc
forall (m :: * -> *). MonadPretty m => a -> m Doc
prettyTCM a
delta2)
        , TCMT IO Doc
"t      =" TCMT IO Doc -> TCMT IO Doc -> TCMT IO Doc
forall (m :: * -> *). Applicative m => m Doc -> m Doc -> m Doc
<+> TCMT IO Doc -> TCMT IO Doc
forall (tcm :: * -> *) a.
(MonadTCM tcm, MonadAddContext tcm, MonadDebug tcm) =>
tcm a -> tcm a
inContextOfT (a -> TCMT IO Doc
forall a (m :: * -> *). (PrettyTCM a, MonadPretty m) => a -> m Doc
forall (m :: * -> *). MonadPretty m => a -> m Doc
prettyTCM a
t)
        ]


-- | splitResult for MakeCase, tries to introduce IApply or ProjP copatterns
splitResult :: QName -> SplitClause -> TCM (Either SplitError [SplitClause])
splitResult :: QName -> SplitClause -> TCM (Either SplitError [SplitClause])
splitResult QName
f SplitClause
sc = do
  TCMT IO (Maybe SplitClause)
-> TCM (Either SplitError [SplitClause])
-> (SplitClause -> TCM (Either SplitError [SplitClause]))
-> TCM (Either SplitError [SplitClause])
forall (m :: * -> *) a b.
Monad m =>
m (Maybe a) -> m b -> (a -> m b) -> m b
caseMaybeM (QName -> SplitClause -> TCMT IO (Maybe SplitClause)
splitResultPath QName
f SplitClause
sc)
             (((Either SplitError Covering -> Either SplitError [SplitClause])
-> TCMT IO (Either SplitError Covering)
-> TCM (Either SplitError [SplitClause])
forall a b. (a -> b) -> TCMT IO a -> TCMT IO b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ((Either SplitError Covering -> Either SplitError [SplitClause])
 -> TCMT IO (Either SplitError Covering)
 -> TCM (Either SplitError [SplitClause]))
-> ((Covering -> [SplitClause])
    -> Either SplitError Covering -> Either SplitError [SplitClause])
-> (Covering -> [SplitClause])
-> TCMT IO (Either SplitError Covering)
-> TCM (Either SplitError [SplitClause])
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Covering -> [SplitClause])
-> Either SplitError Covering -> Either SplitError [SplitClause]
forall a b. (a -> b) -> Either SplitError a -> Either SplitError b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap) Covering -> [SplitClause]
splitClauses (TCMT IO (Either SplitError Covering)
 -> TCM (Either SplitError [SplitClause]))
-> TCMT IO (Either SplitError Covering)
-> TCM (Either SplitError [SplitClause])
forall a b. (a -> b) -> a -> b
$ QName -> SplitClause -> TCMT IO (Either SplitError Covering)
splitResultRecord QName
f SplitClause
sc)
             (Either SplitError [SplitClause]
-> TCM (Either SplitError [SplitClause])
forall a. a -> TCMT IO a
forall (m :: * -> *) a. Monad m => a -> m a
return (Either SplitError [SplitClause]
 -> TCM (Either SplitError [SplitClause]))
-> (SplitClause -> Either SplitError [SplitClause])
-> SplitClause
-> TCM (Either SplitError [SplitClause])
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [SplitClause] -> Either SplitError [SplitClause]
forall a b. b -> Either a b
Right ([SplitClause] -> Either SplitError [SplitClause])
-> (SplitClause -> [SplitClause])
-> SplitClause
-> Either SplitError [SplitClause]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (SplitClause -> [SplitClause] -> [SplitClause]
forall a. a -> [a] -> [a]
:[]))


-- | Tries to split the result to introduce an IApply pattern.
splitResultPath :: QName -> SplitClause -> TCM (Maybe SplitClause)
splitResultPath :: QName -> SplitClause -> TCMT IO (Maybe SplitClause)
splitResultPath QName
f sc :: SplitClause
sc@(SClause Telescope
tel [NamedArg SplitPattern]
ps Substitution' SplitPattern
_ Map CheckpointId (Substitution' Term)
_ Maybe (Dom Type)
target) = do
  Maybe (Dom Type)
-> TCMT IO (Maybe SplitClause)
-> (Dom Type -> TCMT IO (Maybe SplitClause))
-> TCMT IO (Maybe SplitClause)
forall a b. Maybe a -> b -> (a -> b) -> b
caseMaybe Maybe (Dom Type)
target (Maybe SplitClause -> TCMT IO (Maybe SplitClause)
forall a. a -> TCMT IO a
forall (m :: * -> *) a. Monad m => a -> m a
return Maybe SplitClause
forall a. Maybe a
Nothing) ((Dom Type -> TCMT IO (Maybe SplitClause))
 -> TCMT IO (Maybe SplitClause))
-> (Dom Type -> TCMT IO (Maybe SplitClause))
-> TCMT IO (Maybe SplitClause)
forall a b. (a -> b) -> a -> b
$ \ Dom Type
t -> do
        TCMT IO (Maybe (Dom Type, Abs Type))
-> TCMT IO (Maybe SplitClause)
-> ((Dom Type, Abs Type) -> TCMT IO (Maybe SplitClause))
-> TCMT IO (Maybe SplitClause)
forall (m :: * -> *) a b.
Monad m =>
m (Maybe a) -> m b -> (a -> m b) -> m b
caseMaybeM (Type -> TCMT IO (Maybe (Dom Type, Abs Type))
forall (m :: * -> *).
PureTCM m =>
Type -> m (Maybe (Dom Type, Abs Type))
isPath (Dom Type -> Type
forall t e. Dom' t e -> e
unDom Dom Type
t)) (Maybe SplitClause -> TCMT IO (Maybe SplitClause)
forall a. a -> TCMT IO a
forall (m :: * -> *) a. Monad m => a -> m a
return Maybe SplitClause
forall a. Maybe a
Nothing) (((Dom Type, Abs Type) -> TCMT IO (Maybe SplitClause))
 -> TCMT IO (Maybe SplitClause))
-> ((Dom Type, Abs Type) -> TCMT IO (Maybe SplitClause))
-> TCMT IO (Maybe SplitClause)
forall a b. (a -> b) -> a -> b
$ \ (Dom Type, Abs Type)
_ -> do
               (TelV i b, boundary) <- Int -> Type -> TCM (TelV Type, Boundary)
forall (m :: * -> *).
PureTCM m =>
Int -> Type -> m (TelV Type, Boundary)
telViewUpToPathBoundary' Int
1 (Dom Type -> Type
forall t e. Dom' t e -> e
unDom Dom Type
t)
               let tel' = Telescope -> Telescope -> Telescope
forall t. Abstract t => Telescope -> t -> t
abstract Telescope
tel Telescope
i
                   rho  = Int -> Substitution' a
forall a. Int -> Substitution' a
raiseS Int
1
                   ps' = Substitution' (SubstArg [NamedArg SplitPattern])
-> [NamedArg SplitPattern] -> [NamedArg SplitPattern]
forall a. Subst a => Substitution' (SubstArg a) -> a -> a
applySubst Substitution' SplitPattern
Substitution' (SubstArg [NamedArg SplitPattern])
forall a. Substitution' a
rho (SplitClause -> [NamedArg SplitPattern]
scPats SplitClause
sc) [NamedArg SplitPattern]
-> [NamedArg SplitPattern] -> [NamedArg SplitPattern]
forall a. [a] -> [a] -> [a]
++ Telescope -> Boundary -> [NamedArg SplitPattern]
forall a.
DeBruijn a =>
Telescope -> Boundary -> [NamedArg (Pattern' a)]
telePatterns Telescope
i Boundary
boundary
                   cps' = Substitution' (SubstArg (Map CheckpointId (Substitution' Term)))
-> Map CheckpointId (Substitution' Term)
-> Map CheckpointId (Substitution' Term)
forall a. Subst a => Substitution' (SubstArg a) -> a -> a
applySubst Substitution' Term
Substitution' (SubstArg (Map CheckpointId (Substitution' Term)))
forall a. Substitution' a
rho (SplitClause -> Map CheckpointId (Substitution' Term)
scCheckpoints SplitClause
sc)
                   target' = Dom Type -> Maybe (Dom Type)
forall a. a -> Maybe a
Just (Dom Type -> Maybe (Dom Type)) -> Dom Type -> Maybe (Dom Type)
forall a b. (a -> b) -> a -> b
$ Type
b Type -> Dom Type -> Dom Type
forall a b. a -> Dom' Term b -> Dom' Term a
forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$ Dom Type
t
               return . Just $ SClause tel' ps' idS cps' target'

-- | @splitResultRecord f sc = return res@
--
--   If the target type of @sc@ is a record type, a covering set of
--   split clauses is returned (@sc@ extended by all valid projection patterns),
--   otherwise @res == Left _@.
--   Note that the empty set of split clauses is returned if the record has no fields.
splitResultRecord :: QName -> SplitClause -> TCM (Either SplitError Covering)
splitResultRecord :: QName -> SplitClause -> TCMT IO (Either SplitError Covering)
splitResultRecord QName
f sc :: SplitClause
sc@(SClause Telescope
tel [NamedArg SplitPattern]
ps Substitution' SplitPattern
_ Map CheckpointId (Substitution' Term)
_ Maybe (Dom Type)
target) = do
  [Char] -> Int -> TCMT IO Doc -> TCMT IO ()
forall (m :: * -> *).
MonadDebug m =>
[Char] -> Int -> TCMT IO Doc -> m ()
reportSDoc [Char]
"tc.cover.split" Int
10 (TCMT IO Doc -> TCMT IO ()) -> TCMT IO Doc -> TCMT IO ()
forall a b. (a -> b) -> a -> b
$ [TCMT IO Doc] -> TCMT IO Doc
forall (m :: * -> *) (t :: * -> *).
(Applicative m, Foldable t) =>
t (m Doc) -> m Doc
vcat
    [ TCMT IO Doc
"splitting result:"
    , Int -> TCMT IO Doc -> TCMT IO Doc
forall (m :: * -> *). Functor m => Int -> m Doc -> m Doc
nest Int
2 (TCMT IO Doc -> TCMT IO Doc) -> TCMT IO Doc -> TCMT IO Doc
forall a b. (a -> b) -> a -> b
$ TCMT IO Doc
"f      =" TCMT IO Doc -> TCMT IO Doc -> TCMT IO Doc
forall (m :: * -> *). Applicative m => m Doc -> m Doc -> m Doc
<+> QName -> TCMT IO Doc
forall a (m :: * -> *). (PrettyTCM a, MonadPretty m) => a -> m Doc
forall (m :: * -> *). MonadPretty m => QName -> m Doc
prettyTCM QName
f
    , Int -> TCMT IO Doc -> TCMT IO Doc
forall (m :: * -> *). Functor m => Int -> m Doc -> m Doc
nest Int
2 (TCMT IO Doc -> TCMT IO Doc) -> TCMT IO Doc -> TCMT IO Doc
forall a b. (a -> b) -> a -> b
$ TCMT IO Doc
"target =" TCMT IO Doc -> TCMT IO Doc -> TCMT IO Doc
forall (m :: * -> *). Applicative m => m Doc -> m Doc -> m Doc
<+> Telescope -> TCMT IO Doc -> TCMT IO Doc
forall b (m :: * -> *) a.
(AddContext b, MonadAddContext m) =>
b -> m a -> m a
forall (m :: * -> *) a.
MonadAddContext m =>
Telescope -> m a -> m a
addContext Telescope
tel (TCMT IO Doc
-> (Dom Type -> TCMT IO Doc) -> Maybe (Dom Type) -> TCMT IO Doc
forall b a. b -> (a -> b) -> Maybe a -> b
maybe TCMT IO Doc
forall a. Null a => a
empty Dom Type -> TCMT IO Doc
forall a (m :: * -> *). (PrettyTCM a, MonadPretty m) => a -> m Doc
forall (m :: * -> *). MonadPretty m => Dom Type -> m Doc
prettyTCM Maybe (Dom Type)
target)
    ]
  -- if we want to split projections, but have no target type, we give up
  let failure :: a -> TCMT IO (Either a b)
failure = Either a b -> TCMT IO (Either a b)
forall a. a -> TCMT IO a
forall (m :: * -> *) a. Monad m => a -> m a
return (Either a b -> TCMT IO (Either a b))
-> (a -> Either a b) -> a -> TCMT IO (Either a b)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> Either a b
forall a b. a -> Either a b
Left
  Maybe (Dom Type)
-> TCMT IO (Either SplitError Covering)
-> (Dom Type -> TCMT IO (Either SplitError Covering))
-> TCMT IO (Either SplitError Covering)
forall a b. Maybe a -> b -> (a -> b) -> b
caseMaybe Maybe (Dom Type)
target (SplitError -> TCMT IO (Either SplitError Covering)
forall {a} {b}. a -> TCMT IO (Either a b)
failure SplitError
CosplitNoTarget) ((Dom Type -> TCMT IO (Either SplitError Covering))
 -> TCMT IO (Either SplitError Covering))
-> (Dom Type -> TCMT IO (Either SplitError Covering))
-> TCMT IO (Either SplitError Covering)
forall a b. (a -> b) -> a -> b
$ \ Dom Type
t -> do
    (Telescope
-> TCMT IO (Maybe (QName, Args, RecordData))
-> TCMT IO (Maybe (QName, Args, RecordData))
forall b (m :: * -> *) a.
(AddContext b, MonadAddContext m) =>
b -> m a -> m a
forall (m :: * -> *) a.
MonadAddContext m =>
Telescope -> m a -> m a
addContext Telescope
tel (TCMT IO (Maybe (QName, Args, RecordData))
 -> TCMT IO (Maybe (QName, Args, RecordData)))
-> TCMT IO (Maybe (QName, Args, RecordData))
-> TCMT IO (Maybe (QName, Args, RecordData))
forall a b. (a -> b) -> a -> b
$ Type -> TCMT IO (Maybe (QName, Args, RecordData))
forall (m :: * -> *).
PureTCM m =>
Type -> m (Maybe (QName, Args, RecordData))
isRecordType (Type -> TCMT IO (Maybe (QName, Args, RecordData)))
-> Type -> TCMT IO (Maybe (QName, Args, RecordData))
forall a b. (a -> b) -> a -> b
$ Dom Type -> Type
forall t e. Dom' t e -> e
unDom Dom Type
t) TCMT IO (Maybe (QName, Args, RecordData))
-> (Maybe (QName, Args, RecordData)
    -> TCMT IO (Either SplitError Covering))
-> TCMT IO (Either SplitError Covering)
forall a b. TCMT IO a -> (a -> TCMT IO b) -> TCMT IO b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \case
      Maybe (QName, Args, RecordData)
Nothing -> Telescope
-> TCMT IO (Either SplitError Covering)
-> TCMT IO (Either SplitError Covering)
forall b (m :: * -> *) a.
(AddContext b, MonadAddContext m) =>
b -> m a -> m a
forall (m :: * -> *) a.
MonadAddContext m =>
Telescope -> m a -> m a
addContext Telescope
tel (TCMT IO (Either SplitError Covering)
 -> TCMT IO (Either SplitError Covering))
-> TCMT IO (Either SplitError Covering)
-> TCMT IO (Either SplitError Covering)
forall a b. (a -> b) -> a -> b
$ do
        SplitError -> TCMT IO (Either SplitError Covering)
forall {a} {b}. a -> TCMT IO (Either a b)
failure (SplitError -> TCMT IO (Either SplitError Covering))
-> (Closure Type -> SplitError)
-> Closure Type
-> TCMT IO (Either SplitError Covering)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Closure Type -> SplitError
CosplitNoRecordType (Closure Type -> TCMT IO (Either SplitError Covering))
-> TCM (Closure Type) -> TCMT IO (Either SplitError Covering)
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< Type -> TCM (Closure Type)
forall (m :: * -> *) a.
(MonadTCEnv m, ReadTCState m) =>
a -> m (Closure a)
buildClosure (Dom Type -> Type
forall t e. Dom' t e -> e
unDom Dom Type
t)
      Just (QName
_r, Args
vs, RecordData{ _recFields :: RecordData -> [Dom QName]
_recFields = [Dom QName]
fs }) -> do
        [Char] -> Int -> TCMT IO Doc -> TCMT IO ()
forall (m :: * -> *).
MonadDebug m =>
[Char] -> Int -> TCMT IO Doc -> m ()
reportSDoc [Char]
"tc.cover" Int
20 (TCMT IO Doc -> TCMT IO ()) -> TCMT IO Doc -> TCMT IO ()
forall a b. (a -> b) -> a -> b
$ [TCMT IO Doc] -> TCMT IO Doc
forall (m :: * -> *) (t :: * -> *).
(Applicative m, Foldable t) =>
t (m Doc) -> m Doc
sep
          [ [Char] -> TCMT IO Doc
forall (m :: * -> *). Applicative m => [Char] -> m Doc
text ([Char] -> TCMT IO Doc) -> [Char] -> TCMT IO Doc
forall a b. (a -> b) -> a -> b
$ [Char]
"we are of record type _r = " [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ QName -> [Char]
forall a. Pretty a => a -> [Char]
prettyShow QName
_r
          , [Char] -> TCMT IO Doc
forall (m :: * -> *). Applicative m => [Char] -> m Doc
text   [Char]
"applied to parameters vs =" TCMT IO Doc -> TCMT IO Doc -> TCMT IO Doc
forall (m :: * -> *). Applicative m => m Doc -> m Doc -> m Doc
<+> Telescope -> TCMT IO Doc -> TCMT IO Doc
forall b (m :: * -> *) a.
(AddContext b, MonadAddContext m) =>
b -> m a -> m a
forall (m :: * -> *) a.
MonadAddContext m =>
Telescope -> m a -> m a
addContext Telescope
tel (Args -> TCMT IO Doc
forall a (m :: * -> *). (PrettyTCM a, MonadPretty m) => a -> m Doc
forall (m :: * -> *). MonadPretty m => Args -> m Doc
prettyTCM Args
vs)
          , [Char] -> TCMT IO Doc
forall (m :: * -> *). Applicative m => [Char] -> m Doc
text ([Char] -> TCMT IO Doc) -> [Char] -> TCMT IO Doc
forall a b. (a -> b) -> a -> b
$ [Char]
"and have fields       fs = " [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Dom QName] -> [Char]
forall a. Pretty a => a -> [Char]
prettyShow [Dom QName]
fs
          ]
        -- Andreas, 2018-06-09, issue #2170, we always have irrelevant projections
        -- available on the lhs.
        -- -- Andreas, 2018-03-19, issue #2971, check that we have a "strong" record type,
        -- -- i.e., with all the projections.  Otherwise, we may not split.
        -- ifNotM (strongRecord fs) (failure CosplitIrrelevantProjections) $ {-else-} do
        let es :: Elims
es = NAPs -> Elims
patternsToElims (NAPs -> Elims) -> NAPs -> Elims
forall a b. (a -> b) -> a -> b
$ [NamedArg SplitPattern] -> NAPs
fromSplitPatterns [NamedArg SplitPattern]
ps
        -- Note: module parameters are part of ps
        let self :: Arg Term
self  = Term -> Arg Term
forall a. a -> Arg a
defaultArg (Term -> Arg Term) -> Term -> Arg Term
forall a b. (a -> b) -> a -> b
$ QName -> Elims -> Term
Def QName
f [] Term -> Elims -> Term
forall t. Apply t => t -> Elims -> t
`applyE` Elims
es
            pargs :: Args
pargs = Args
vs Args -> Args -> Args
forall a. [a] -> [a] -> [a]
++ [Arg Term
self]
            fieldValues :: [Term]
fieldValues = [Dom QName] -> (Dom QName -> Term) -> [Term]
forall (m :: * -> *) a b. Functor m => m a -> (a -> b) -> m b
for [Dom QName]
fs ((Dom QName -> Term) -> [Term]) -> (Dom QName -> Term) -> [Term]
forall a b. (a -> b) -> a -> b
$ \ Dom QName
proj -> Arg Term -> Term
forall e. Arg e -> e
unArg Arg Term
self Term -> Elims -> Term
forall t. Apply t => t -> Elims -> t
`applyE` [ProjOrigin -> QName -> Elim' Term
forall a. ProjOrigin -> QName -> Elim' a
Proj ProjOrigin
ProjSystem (Dom QName -> QName
forall t e. Dom' t e -> e
unDom Dom QName
proj)]
        [Char] -> Int -> TCMT IO Doc -> TCMT IO ()
forall (m :: * -> *).
MonadDebug m =>
[Char] -> Int -> TCMT IO Doc -> m ()
reportSDoc [Char]
"tc.cover" Int
20 (TCMT IO Doc -> TCMT IO ()) -> TCMT IO Doc -> TCMT IO ()
forall a b. (a -> b) -> a -> b
$ Telescope -> TCMT IO Doc -> TCMT IO Doc
forall b (m :: * -> *) a.
(AddContext b, MonadAddContext m) =>
b -> m a -> m a
forall (m :: * -> *) a.
MonadAddContext m =>
Telescope -> m a -> m a
addContext Telescope
tel (TCMT IO Doc -> TCMT IO Doc) -> TCMT IO Doc -> TCMT IO Doc
forall a b. (a -> b) -> a -> b
$ [TCMT IO Doc] -> TCMT IO Doc
forall (m :: * -> *) (t :: * -> *).
(Applicative m, Foldable t) =>
t (m Doc) -> m Doc
sep
          [ [Char] -> TCMT IO Doc
forall (m :: * -> *). Applicative m => [Char] -> m Doc
text   [Char]
"we are              self =" TCMT IO Doc -> TCMT IO Doc -> TCMT IO Doc
forall (m :: * -> *). Applicative m => m Doc -> m Doc -> m Doc
<+> Term -> TCMT IO Doc
forall a (m :: * -> *). (PrettyTCM a, MonadPretty m) => a -> m Doc
forall (m :: * -> *). MonadPretty m => Term -> m Doc
prettyTCM (Arg Term -> Term
forall e. Arg e -> e
unArg Arg Term
self)
          , [Char] -> TCMT IO Doc
forall (m :: * -> *). Applicative m => [Char] -> m Doc
text   [Char]
"            field values =" TCMT IO Doc -> TCMT IO Doc -> TCMT IO Doc
forall (m :: * -> *). Applicative m => m Doc -> m Doc -> m Doc
<+> [Term] -> TCMT IO Doc
forall a (m :: * -> *). (PrettyTCM a, MonadPretty m) => a -> m Doc
forall (m :: * -> *). MonadPretty m => [Term] -> m Doc
prettyTCM [Term]
fieldValues
          ]
        let n :: Arg Int
n = Int -> Arg Int
forall a. a -> Arg a
defaultArg (Int -> Arg Int) -> Int -> Arg Int
forall a b. (a -> b) -> a -> b
$ Permutation -> Int
permRange (Permutation -> Int) -> Permutation -> Int
forall a b. (a -> b) -> a -> b
$ Permutation -> Maybe Permutation -> Permutation
forall a. a -> Maybe a -> a
fromMaybe Permutation
forall a. HasCallStack => a
__IMPOSSIBLE__ (Maybe Permutation -> Permutation)
-> Maybe Permutation -> Permutation
forall a b. (a -> b) -> a -> b
$ NAPs -> Maybe Permutation
dbPatPerm (NAPs -> Maybe Permutation) -> NAPs -> Maybe Permutation
forall a b. (a -> b) -> a -> b
$ [NamedArg SplitPattern] -> NAPs
fromSplitPatterns [NamedArg SplitPattern]
ps
            -- Andreas & James, 2013-11-19 includes the dot patterns!
            -- See test/succeed/CopatternsAndDotPatterns.agda for a case with dot patterns
            -- and copatterns which fails for @n = size tel@ with a broken case tree.

        -- Andreas, 2016-07-22 read the style of projections from the user's lips
        projOrigin <- TCMT IO Bool
-> TCMT IO ProjOrigin -> TCMT IO ProjOrigin -> TCMT IO ProjOrigin
forall (m :: * -> *) a. Monad m => m Bool -> m a -> m a -> m a
ifM (PragmaOptions -> Bool
optPostfixProjections (PragmaOptions -> Bool) -> TCMT IO PragmaOptions -> TCMT IO Bool
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> TCMT IO PragmaOptions
forall (m :: * -> *). HasOptions m => m PragmaOptions
pragmaOptions) (ProjOrigin -> TCMT IO ProjOrigin
forall a. a -> TCMT IO a
forall (m :: * -> *) a. Monad m => a -> m a
return ProjOrigin
ProjPostfix) (ProjOrigin -> TCMT IO ProjOrigin
forall a. a -> TCMT IO a
forall (m :: * -> *) a. Monad m => a -> m a
return ProjOrigin
ProjPrefix)
        Right . Covering n <$> do
          forM (zip fs $ List.inits fieldValues) $ \ (Dom QName
proj, [Term]
prevFields) -> do
            -- compute the new target
            dType <- Definition -> Type
defType (Definition -> Type) -> TCMT IO Definition -> TCM Type
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> do QName -> TCMT IO Definition
forall (m :: * -> *). HasConstInfo m => QName -> m Definition
getConstInfo (QName -> TCMT IO Definition) -> QName -> TCMT IO Definition
forall a b. (a -> b) -> a -> b
$ Dom QName -> QName
forall t e. Dom' t e -> e
unDom Dom QName
proj -- WRONG: typeOfConst $ unArg proj
            let -- Substitution for parameters and previous fields. Needs to be applied to potential
                -- tactic in proj.
                fieldSub = [Term] -> [Term]
forall a. [a] -> [a]
reverse ((Arg Term -> Term) -> Args -> [Term]
forall a b. (a -> b) -> [a] -> [b]
map Arg Term -> Term
forall e. Arg e -> e
unArg Args
vs [Term] -> [Term] -> [Term]
forall a. [a] -> [a] -> [a]
++ [Term]
prevFields) [Term] -> Substitution' Term -> Substitution' Term
forall a. DeBruijn a => [a] -> Substitution' a -> Substitution' a
++# Impossible -> Substitution' Term
forall a. Impossible -> Substitution' a
EmptyS Impossible
HasCallStack => Impossible
impossible
                proj'    = Substitution' (SubstArg (Dom QName)) -> Dom QName -> Dom QName
forall a. Subst a => Substitution' (SubstArg a) -> a -> a
applySubst Substitution' Term
Substitution' (SubstArg (Dom QName))
fieldSub Dom QName
proj
                -- type of projection instantiated at self
                target' = Dom Type -> Maybe (Dom Type)
forall a. a -> Maybe a
Just (Dom Type -> Maybe (Dom Type)) -> Dom Type -> Maybe (Dom Type)
forall a b. (a -> b) -> a -> b
$ Dom QName
proj' Dom QName -> Type -> Dom Type
forall (f :: * -> *) a b. Functor f => f a -> b -> f b
$> Type
dType Type -> Args -> Type
`piApply` Args
pargs      -- Always visible (#2287)
                projArg = (QName -> Named NamedName SplitPattern)
-> Arg QName -> NamedArg SplitPattern
forall a b. (a -> b) -> Arg a -> Arg b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (Maybe NamedName -> SplitPattern -> Named NamedName SplitPattern
forall name a. Maybe name -> a -> Named name a
Named Maybe NamedName
forall a. Maybe a
Nothing (SplitPattern -> Named NamedName SplitPattern)
-> (QName -> SplitPattern) -> QName -> Named NamedName SplitPattern
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ProjOrigin -> QName -> SplitPattern
forall x. ProjOrigin -> QName -> Pattern' x
ProjP ProjOrigin
projOrigin) (Arg QName -> NamedArg SplitPattern)
-> Arg QName -> NamedArg SplitPattern
forall a b. (a -> b) -> a -> b
$ Dom QName -> Arg QName
forall t a. Dom' t a -> Arg a
argFromDom (Dom QName -> Arg QName) -> Dom QName -> Arg QName
forall a b. (a -> b) -> a -> b
$ Hiding -> Dom QName -> Dom QName
forall a. LensHiding a => Hiding -> a -> a
setHiding Hiding
NotHidden Dom QName
proj
                sc' = SplitClause
sc { scPats   = scPats sc ++ [projArg]
                         , scSubst  = idS
                         , scTarget = target'
                         }
            reportSDoc "tc.cover.copattern" 40 $ vcat
              [ "fieldSub for" <+> prettyTCM (unDom proj)
              , nest 2 $ pretty fieldSub ]
            return (SplitCon (unDom proj), (sc', NoInfo))
  -- Andreas, 2018-06-09, issue #2170: splitting with irrelevant fields is always fine!
  -- where
  -- -- A record type is strong if it has all the projections.
  -- -- This is the case if --irrelevant-projections or no field is irrelevant.
  -- -- TODO: what about shape irrelevance?
  -- strongRecord :: [Arg QName] -> TCM Bool
  -- strongRecord fs = (optIrrelevantProjections <$> pragmaOptions) `or2M`
  --   (return $ not $ any isIrrelevant fs)


-- * Boring instances

-- | For debugging only.
instance PrettyTCM SplitClause where
  prettyTCM :: forall (m :: * -> *). MonadPretty m => SplitClause -> m Doc
prettyTCM (SClause Telescope
tel [NamedArg SplitPattern]
pats Substitution' SplitPattern
sigma Map CheckpointId (Substitution' Term)
cps Maybe (Dom Type)
target) = [m Doc] -> m Doc
forall (m :: * -> *) (t :: * -> *).
(Applicative m, Foldable t) =>
t (m Doc) -> m Doc
sep
    [ m Doc
"SplitClause"
    , Int -> m Doc -> m Doc
forall (m :: * -> *). Functor m => Int -> m Doc -> m Doc
nest Int
2 (m Doc -> m Doc) -> m Doc -> m Doc
forall a b. (a -> b) -> a -> b
$ [m Doc] -> m Doc
forall (m :: * -> *) (t :: * -> *).
(Applicative m, Foldable t) =>
t (m Doc) -> m Doc
vcat
      [ m Doc
"tel          =" m Doc -> m Doc -> m Doc
forall (m :: * -> *). Applicative m => m Doc -> m Doc -> m Doc
<+> Telescope -> m Doc
forall a (m :: * -> *). (PrettyTCM a, MonadPretty m) => a -> m Doc
forall (m :: * -> *). MonadPretty m => Telescope -> m Doc
prettyTCM Telescope
tel
      , m Doc
"pats         =" m Doc -> m Doc -> m Doc
forall (m :: * -> *). Applicative m => m Doc -> m Doc -> m Doc
<+> [m Doc] -> m Doc
forall (m :: * -> *) (t :: * -> *).
(Applicative m, Foldable t) =>
t (m Doc) -> m Doc
sep ((NamedArg SplitPattern -> m Doc)
-> [NamedArg SplitPattern] -> [m Doc]
forall a b. (a -> b) -> [a] -> [b]
map (SplitPattern -> m Doc
forall a (m :: * -> *). (PrettyTCM a, MonadPretty m) => a -> m Doc
forall (m :: * -> *). MonadPretty m => SplitPattern -> m Doc
prettyTCM (SplitPattern -> m Doc)
-> (NamedArg SplitPattern -> SplitPattern)
-> NamedArg SplitPattern
-> m Doc
forall b c a. (b -> c) -> (a -> b) -> a -> c
. NamedArg SplitPattern -> SplitPattern
forall a. NamedArg a -> a
namedArg) [NamedArg SplitPattern]
pats)
      , m Doc
"subst        =" m Doc -> m Doc -> m Doc
forall (m :: * -> *). Applicative m => m Doc -> m Doc -> m Doc
<+> Substitution' SplitPattern -> m Doc
forall a (m :: * -> *). (PrettyTCM a, MonadPretty m) => a -> m Doc
forall (m :: * -> *).
MonadPretty m =>
Substitution' SplitPattern -> m Doc
prettyTCM Substitution' SplitPattern
sigma
      , m Doc
"checkpoints  =" m Doc -> m Doc -> m Doc
forall (m :: * -> *). Applicative m => m Doc -> m Doc -> m Doc
<+> Map CheckpointId (Substitution' Term) -> m Doc
forall a (m :: * -> *). (PrettyTCM a, MonadPretty m) => a -> m Doc
forall (m :: * -> *).
MonadPretty m =>
Map CheckpointId (Substitution' Term) -> m Doc
prettyTCM Map CheckpointId (Substitution' Term)
cps
      , m Doc
"target       =" m Doc -> m Doc -> m Doc
forall (m :: * -> *). Applicative m => m Doc -> m Doc -> m Doc
<+> do
          Maybe (Dom Type) -> m Doc -> (Dom Type -> m Doc) -> m Doc
forall a b. Maybe a -> b -> (a -> b) -> b
caseMaybe Maybe (Dom Type)
target m Doc
forall a. Null a => a
empty ((Dom Type -> m Doc) -> m Doc) -> (Dom Type -> m Doc) -> m Doc
forall a b. (a -> b) -> a -> b
$ \ Dom Type
t -> do
            Telescope -> m Doc -> m Doc
forall b (m :: * -> *) a.
(AddContext b, MonadAddContext m) =>
b -> m a -> m a
forall (m :: * -> *) a.
MonadAddContext m =>
Telescope -> m a -> m a
addContext Telescope
tel (m Doc -> m Doc) -> m Doc -> m Doc
forall a b. (a -> b) -> a -> b
$ Dom Type -> m Doc
forall a (m :: * -> *). (PrettyTCM a, MonadPretty m) => a -> m Doc
forall (m :: * -> *). MonadPretty m => Dom Type -> m Doc
prettyTCM Dom Type
t
      -- Triggers crash (see Issue 1374).
      -- , "subst target = " <+> do
      --     caseMaybe target empty $ \ t -> do
      --       addContext tel $ prettyTCM $ applySubst sigma t
      ]
    ]