{-# LANGUAGE CPP #-}-- | Detect if a datatype could be represented as a primitive integer.-- If it has one constructor with no arguments and one with a recursive-- argument this is true. This is done using IrrFilters which filter out-- forced arguments, so for example Fin becomes primitive.moduleAgda.Compiler.Epic.NatDetectionwhereimportControl.ApplicativeimportControl.MonadimportControl.Monad.StateimportData.FunctionimportData.ListimportqualifiedData.MapasMimportData.MaybeimportAgda.Syntax.CommonimportAgda.Syntax.InternalimportAgda.TypeChecking.MonadimportAgda.TypeChecking.SubstituteimportAgda.Utils.Monad(andM)importAgda.Compiler.Epic.CompileStateimportAgda.Compiler.Epic.Interface#include "../../undefined.h"importAgda.Utils.ImpossibleimportqualifiedAgda.Utils.HashMapasHM-- | Get a list of all the datatypes that look like nats. The [QName] is on the-- form [zeroConstr, sucConstr]getNatish::CompileTCM[(ForcedArgs,[QName])]getNatish=dosig<-lift(gets(sigDefinitions.stImports))letdefs=HM.toListsigfmapcatMaybes$forMdefs$\(q,def)->casetheDefdefofd@(Datatype{})->isNatishqd_->returnNothingisNatish::QName->Defn->CompileTCM(Maybe(ForcedArgs,[QName]))isNatishqd=do-- A datatype ...casedataConsdofconstrs|lengthconstrs==2->do-- with two constructors ...b<-andM$mapconstrInScopeconstrsifbthendoz<-zipconstrs<$>mapMgetForcedArgsconstrscasesortBy(compare`on`nrRel.snd)zof[(cz,fz),(cs,fs)]->dosig<-lift(gets(sigDefinitions.stImports))letts=defType$sigHM.!csnr=dataParsdreturn$doguard(nrRelfz==0)-- where one constructor has zero arguments ...guard(nrRelfs==1)-- and the other one one argument ...guard(isRec((fromMaybe__IMPOSSIBLE__$elemIndexNotForcedfs)+nr)tsq)-- which is recursive.return(fs,[cz,cs])-- It's natish!_->returnNothingelsereturnNothing_->returnNothing-- | Count the number of relevant argumentsnrRel::ForcedArgs->IntegernrRel=sum.map(const1).filter(==NotForced)-- | Check if argument n is recursiveisRec::Int->Type->QName->BoolisRec0(El_t)dat=casetofPiarg_->argIsDef(unDomarg)dat_->FalseisRecn(El_t)dat=casetofPi_ab->isRec(n-1)(unAbsab)dat_->FalseargIsDef::Type->QName->BoolargIsDef(El_t)dat=casetofDefq_->q==dat_->False