92
93
-- Andreas, 2010-09-07 cannot split on irrelevant args
93
when (unusableRelevance $ argRelevance a) $
94
when (unusableRelevance $ domRelevance a) $
94
95
typeError $ SplitOnIrrelevant p a
95
96
b <- lift $ litType lit
97
noConstraints (equalType (unArg a) b)
98
noConstraints (equalType (unDom a) b)
99
100
`catchError` \_ -> return False
104
(fmap (LitFocus lit q i) a)
105
(fmap (Problem ps ()) tel)
105
(argFromDom $ fmap (LitFocus lit q i) a)
106
(fmap (\ tel -> Problem ps () tel __IMPOSSIBLE__) tel)
108
109
-- Case: constructor pattern
109
110
(xs, p@(A.ConP _ (A.AmbQ cs) args)) -> do
110
a' <- liftTCM $ reduce $ unArg a
113
-- Type is a meta and constructor is unambiguous,
114
-- in this case try to instantiate the meta.
115
MetaV{} | [c] <- cs -> do
117
Constructor{ conData = d } <- theDef <$> getConstInfo c
118
dt <- defType <$> getConstInfo d
120
El _ (Sort s) <- reduce $ apply dt vs
121
(True <$ noConstraints (equalType a' (El s $ Def d vs)))
122
`catchError` \_ -> return False
123
if not ok then keepGoing else
111
let tryInstantiate a'
113
-- Type is blocked by a meta and constructor is unambiguous,
114
-- in this case try to instantiate the meta.
116
Constructor{ conData = d } <- theDef <$> getConstInfo c
117
dt <- defType <$> getConstInfo d
119
Sort s <- ignoreSharing . unEl <$> reduce (apply dt vs)
120
(True <$ noConstraints (equalType a' (El s $ Def d vs)))
121
`catchError` \_ -> return False
122
if ok then tryAgain else keepGoing
123
| otherwise = keepGoing
124
ifBlockedType (unDom a) (const tryInstantiate) $ \ a' -> do
125
case ignoreSharing $ unEl a' of
126
127
-- Subcase: split type is a Def
128
129
def <- liftTCM $ theDef <$> getConstInfo d
129
130
unless (defIsRecord def) $
130
131
-- cannot split on irrelevant or non-strict things
131
when (unusableRelevance $ argRelevance a) $ do
132
when (unusableRelevance $ domRelevance a) $ do
132
133
-- Andreas, 2011-10-04 unless allowed by option
133
134
allowed <- liftTCM $ optExperimentalIrrelevance <$> pragmaOptions
134
135
unless allowed $ typeError $ SplitOnIrrelevant p a
170
171
whenM (optWithoutK <$> pragmaOptions) $
171
wellFormedIndices pars ixs
173
174
return $ Split mempty
175
(fmap (Focus c args (getRange p) q i d pars ixs) a)
176
(fmap (Problem ps ()) tel)
176
(argFromDom $ fmap (Focus c args (getRange p) q i d pars ixs) a)
177
(fmap (\ tel -> Problem ps () tel __IMPOSSIBLE__) tel)
177
178
-- Subcase: split type is not a Def
179
180
-- Case: neither literal nor constructor pattern
183
let p0 = Problem [p] () (ExtendTel a $ fmap (const EmptyTel) tel)
184
let p0 = Problem [p] () (ExtendTel a $ fmap (const EmptyTel) tel) mempty
184
185
Split p1 xs foc p2 <- underAbstraction a tel $ \tel -> splitP ps qs tel
185
186
return $ Split (mappend p0 p1) xs foc p2
189
:: [Arg Term] -- ^ Parameters.
190
-> [Arg Term] -- ^ Indices.
192
wellFormedIndices pars ixs = do
193
pars <- normalise pars
195
vs <- case constructorApplications ixs of
196
Nothing -> typeError $ IndicesNotConstructorApplications ixs
188
-- | Takes a type, which must be a data or record type application,
189
-- and checks that the indices are constructors (or literals) applied
190
-- to distinct variables which do not occur free in the parameters.
191
-- For the purposes of this check parameters count as constructor
192
-- arguments; parameters are reconstructed from the given type.
194
-- Precondition: The type must be a data or record type application.
196
wellFormedIndices :: Type -> TCM ()
197
wellFormedIndices t = do
200
reportSDoc "tc.lhs.split.well-formed" 10 $
201
fsep [ text "Checking if indices are well-formed:"
202
, nest 2 $ prettyTCM t
205
(pars, ixs) <- normalise =<< case ignoreSharing $ unEl t of
207
def <- getConstInfo d
208
typedArgs <- args `withTypesFrom` defType def
210
let noPars = case theDef def of
211
Datatype { dataPars = n } -> n
212
Record { recPars = n } -> n
214
(pars, ixs) = genericSplitAt noPars typedArgs
215
return (map fst pars, ixs)
219
mvs <- constructorApplications ixs
221
Nothing -> typeError $
222
IndicesNotConstructorApplications (map fst ixs)
198
225
unless (fastDistinct vs) $
199
typeError $ IndexVariablesNotDistinct ixs
200
case filter snd $ zip vs (map (`freeIn` pars) vs) of
202
(v , _) : _ -> typeError $ IndexFreeInParameter v pars
226
typeError $ IndexVariablesNotDistinct vs (map fst ixs)
228
case map fst $ filter snd $ zip vs (map (`freeIn` pars) vs) of
231
typeError $ IndicesFreeInParameters vs (map fst ixs) pars
204
234
-- | If the term consists solely of constructors (or literals)
205
-- applied to variables, then the variables are returned, and
206
-- otherwise nothing.
207
constructorApplication :: Term -> Maybe [Nat]
208
constructorApplication (Var x []) = Just [x]
209
constructorApplication (Con c args) = constructorApplications args
210
constructorApplication (Lit {}) = Just []
211
constructorApplication _ = Nothing
213
constructorApplications :: [Arg Term] -> Maybe [Nat]
214
constructorApplications args =
215
concat <$> mapM (constructorApplication . unArg) args
235
-- applied to variables (after parameter reconstruction), then the
236
-- variables are returned, and otherwise nothing.
237
constructorApplication :: Term
238
-> Type -- ^ The term's type.
240
constructorApplication (Var x []) _ = return (Just [x])
241
constructorApplication (Lit {}) _ = return (Just [])
242
constructorApplication (Shared p) t = constructorApplication (derefPtr p) t
243
constructorApplication (Con c conArgs) (El _ (Def d dataArgs)) = do
244
conDef <- getConstInfo c
245
dataDef <- getConstInfo d
247
let noPars = case theDef dataDef of
248
Datatype { dataPars = n } -> n
249
Record { recPars = n } -> n
251
pars = genericTake noPars dataArgs
252
allArgs = pars ++ conArgs
254
reportSDoc "tc.lhs.split.well-formed" 20 $
255
fsep [ text "Reconstructed parameters:"
257
prettyTCM (Con c []) <+>
258
text "(:" <+> prettyTCM (defType conDef) <> text ")" <+>
259
text "<<" <+> prettyTCM pars <+> text ">>" <+>
263
constructorApplications =<< allArgs `withTypesFrom` defType conDef
265
constructorApplication _ _ = return Nothing
267
constructorApplications :: [(Arg Term, Dom Type)] -> TCM (Maybe [Nat])
268
constructorApplications args = do
269
xs <- mapM (\(e, t) -> constructorApplication (unArg e) (ignoreSharingType $ unDom t))
271
return (concat <$> sequence xs)
273
-- | @args \`withTypesFrom\` t@ returns the arguments @args@ paired up
274
-- with their types, taken from @t@, which is assumed to be a @length
277
-- Precondition: @t@ has to start with @length args@ pis.
279
withTypesFrom :: Args -> Type -> TCM [(Arg Term, Dom Type)]
280
[] `withTypesFrom` _ = return []
281
(arg : args) `withTypesFrom` t = do
283
case ignoreSharing $ unEl t of
284
Pi a b -> ((arg, a) :) <$>
285
args `withTypesFrom` absApp b (unArg arg)