-- | Capture avoiding substitution of expressions in expressions.---- If a binder would capture a variable then it is anonymized-- to deBruijn form.--moduleDDC.Core.Transform.SubstituteXX(SubstituteXX(..),substituteXX,substituteXXs,substituteXArg,substituteXArgs)whereimportDDC.Core.ExpimportDDC.Core.CollectimportDDC.Core.Transform.LiftXimportDDC.Type.CompoundsimportDDC.Core.Transform.SubstituteWXimportDDC.Core.Transform.SubstituteTXimportDDC.Type.Transform.SubstituteTimportDDC.Type.Transform.RenameimportData.MaybeimportqualifiedDDC.Type.EnvasEnvimportqualifiedData.SetasSet-- | Wrapper for `substituteWithX` that determines the set of free names in the-- expression being substituted, and starts with an empty binder stack.substituteXX::(Ordn,SubstituteXXc)=>Bindn->Expan->can->cansubstituteXXbxArgxx|Justu<-takeSubstBoundOfBindb=substituteWithXXxArg(Sub{subBound=u-- Rewrite level-1 binders that have the same name as any-- of the free variables in the expression to substitute, -- or any level-1 binders that expression binds itself.,subConflict1=Set.fromList$(mapMaybetakeNameOfBound$Set.toList$freeTEnv.emptyxArg)++(mapMaybetakeNameOfBind$fst$collectBindsxArg)-- Rewrite level-0 binders that have the same name as any-- of the free variables in the expression to substitute.,subConflict0=Set.fromList$mapMaybetakeNameOfBound$Set.toList$freeXEnv.emptyxArg,subStack1=BindStack[][]00,subStack0=BindStack[][]00,subShadow0=False})xx|otherwise=xx-- | Wrapper for `substituteX` to substitute multiple expressions.substituteXXs::(Ordn,SubstituteXXc)=>[(Bindn,Expan)]->can->cansubstituteXXsbtsx=foldr(uncurrysubstituteXX)xbts-- | Substitute the argument of an application into an expression.-- Perform type substitution for an `XType` -- and witness substitution for an `XWitness`substituteXArg::(Ordn,SubstituteXXc,SubstituteWX(ca),SubstituteTX(ca))=>Bindn->Expan->can->cansubstituteXArgbargx=caseargofXTypet->substituteTXbtxXWitnessw->substituteWXbwx_->substituteXXbargx-- | Wrapper for `substituteXArgs` to substitute multiple arguments.substituteXArgs::(Ordn,SubstituteXXc,SubstituteWX(ca),SubstituteTX(ca))=>[(Bindn,Expan)]->can->cansubstituteXArgsbasx=foldr(uncurrysubstituteXArg)xbas-------------------------------------------------------------------------------classSubstituteXX(c::*->*->*)wheresubstituteWithXX::forallan.Ordn=>Expan->Subn->can->caninstanceSubstituteXXExpwheresubstituteWithXXxArgsubxx={-# SCC substituteWithXX #-}letdownsx=substituteWithXXxArgsxintosx=renameWithsxincasexxofXVarau->casesubstXxArgsubuofLeftu'->XVarau'Rightx->xXCon{}->xxXAppax1x2->XAppa(downsubx1)(downsubx2)XLAMabx->let(sub1,b')=bind1subbx'=downsub1xinXLAMab'x'XLamabx->let(sub1,b')=bind0subbx'=downsub1xinXLamab'x'XLeta(LLetmbx1)x2->letm'=intosubmx1'=downsubx1(sub1,b')=bind0subbx2'=downsub1x2inXLeta(LLetm'b'x1')x2'XLeta(LRecbxs)x2->let(bs,xs)=unzipbxs(sub1,bs')=bind0ssubbsxs'=map(downsub1)xsx2'=downsub1x2inXLeta(LRec(zipbs'xs'))x2'XLeta(LLetRegionsbbs)x2->let(sub1,b')=bind1ssubb(sub2,bs')=bind0ssub1bsx2'=downsub2x2inXLeta(LLetRegionsb'bs')x2'XLeta(LWithRegionuR)x2->XLeta(LWithRegionuR)(downsubx2)XCaseax1alts->XCasea(downsubx1)(map(downsub)alts)XCastaccx1->XCasta(downsubcc)(downsubx1)XTypet->XType(intosubt)XWitnessw->XWitness(intosubw)instanceSubstituteXXAltwheresubstituteWithXXxArgsubaa=letdownsx=substituteWithXXxArgsxincaseaaofAAltPDefaultxBody->AAltPDefault$downsubxBodyAAlt(PDatauConbs)x->let(sub1,bs')=bind0ssubbsx'=downsub1xinAAlt(PDatauConbs')x'instanceSubstituteXXCastwheresubstituteWithXXxArgsubcc=letdownsx=substituteWithXXxArgsxintosx=renameWithsxincaseccofCastWeakenEffecteff->CastWeakenEffect(intosubeff)CastWeakenClosurexs->CastWeakenClosure(map(downsub)xs)CastPurifyw->CastPurify(intosubw)CastForgetw->CastForget(intosubw)-- | Rewrite or substitute into an expression variable.substX::Ordn=>Expan->Subn->Boundn->Either(Boundn)(Expan)substXxArgsubu=casesubstBound(subStack0sub)(subBoundsub)uofLeftu'->Leftu'Rightn|not$subShadow0sub->Right(liftXnxArg)|otherwise->Leftu