ruler-0.4.0.0: src/ARule/ElimCopyRule.cag
-------------------------------------------------------------------------
-- Optimisation: ARule copy rule elimination
-------------------------------------------------------------------------
%%[1 hs module (ARule.ElimCopyRule)
%%]
%%[1 hs export (module Gam, AtDefdGam, AtDefdGam', adGamUnion, ppADGam, CrOrdGam, arlElimCopyRule)
%%]
%%[1 hs import (qualified Data.Map as Map, qualified Data.Set as Set, UHC.Util.Pretty, Common, Expr.Expr, ARule.ARule, Gam)
%%]
%%[1 ag import ({Expr/AbsSynAG}, {ARule/AbsSynAG}, {Expr/SelfAG}, {ARule/SelfAG})
%%]
%%[1 ag import ({ARule/CopyRuleNmAG}, {ARule/EqnDest1NmAG}, {ARule/InCompDestAG})
%%]
%%[1 ag
WRAPPER AGARuleItf
%%]
%%[1 hs
arlElimCopyRule :: [Nm] -> AtDefdGam -> AtDefdGam' -> ARule -> ARule
arlElimCopyRule co ag ag2 rl
= self_Syn_AGARuleItf r2
where r1 = sem_AGARuleItf (AGARuleItf_AGItf rl)
r2 = wrap_AGARuleItf r1
(Inh_AGARuleItf {croNmL_Inh_AGARuleItf = co
,adGam_Inh_AGARuleItf = ag
,ad2Gam_Inh_AGARuleItf = ag2
})
%%]
-------------------------------------------------------------------------
-- Copy rule order, ref to previous node
-------------------------------------------------------------------------
%%[1 hs
type CrOrdGam = Gam Nm Nm
%%]
-------------------------------------------------------------------------
-- Non local attr's defined, threaded?
-------------------------------------------------------------------------
%%[1 hs
type AtDefdGam = Gam Nm Bool
type AtDefdGam' = Gam Nm (Set.Set Nm)
adGamUnion :: AtDefdGam' -> AtDefdGam' -> AtDefdGam'
adGamUnion = gamUnionWith Set.union
ppADGam :: AtDefdGam' -> PP_Doc
ppADGam = ppGam . gamMap (pp.show)
adGamIsThr :: AtDefdGam -> AtDefdGam' -> CrOrdGam -> Nm -> Nm -> Nm -> Bool
adGamIsThr ag1 ag2 cg
= if gamIsEmpty ag2 then isThr1 else isThr2
where isThr1 _ _ nAt = gamFindWithDefault False nAt ag1
isThr2 nNd1 nNd2 nAt
= case gamLookup nNd2 cg of
Nothing -> False
Just nNd1'
| nNd1 == nNd1'
-> isComingOut
| not isComingOut
-> isThr2 nNd1 nNd1' nAt
| otherwise
-> False
where isComingOut = maybe False (nNd1' `Set.member`) $ gamLookup nAt ag2
%%]
-------------------------------------------------------------------------
-- Context
-------------------------------------------------------------------------
%%[1 ag
ATTR AllARuleRule AllARuleEqn AGARuleItf [ adGam: AtDefdGam | | ]
ATTR AllARuleRule AllARuleEqn AGARuleItf [ ad2Gam: {AtDefdGam'} | | ]
ATTR AllARuleRule AllARuleEqn [ croGam: CrOrdGam | | ]
SEM AGARuleItf
| AGItf rule . croGam = fst . foldl (\(g,pn) n -> (gamInsert n pn g,n)) (emptyGam,head @lhs.croNmL) $ tail @lhs.croNmL
%%]
-------------------------------------------------------------------------
-- Replica
-------------------------------------------------------------------------
%%[1 ag
ATTR AEqns AEqn [ | | replCrEqns USE {++} {[]}: {[AEqn]} ]
SEM AEqn
| Eqn lhs . replCrEqns = let -- isThr n = gamFindWithDefault False n @lhs.adGam
isThr = adGamIsThr @lhs.adGam @lhs.ad2Gam @lhs.croGam
isPrev1 n1 n2 = maybe False (==n1) $ gamLookup n2 @lhs.croGam
isPrev = if gamIsEmpty @lhs.ad2Gam then isPrev1 else \_ _ -> True
in case (@dest.mbSingleANm,@val.mbSingleANm) of
(Just (ANm_Node nn dn),Just (ANm_Lhs sn _)) | gamIsEmpty @lhs.ad2Gam && dn == sn && not (isThr nmLhs nn dn)
-> []
(Just (ANm_Node nn dn),Just (ANm_Lhs sn _)) | dn == sn && (isThr nmLhs nn dn) && nmLhs `isPrev` nn
-> []
(Just (ANm_Node nn1 dn),Just (ANm_Node nn2 sn)) | dn == sn && (isThr nn2 nn1 dn) && nn2 `isPrev` nn1
-> []
(Just (ANm_Lhs dn _),Just (ANm_Node nn sn)) | dn == sn {- && (isThr sn) -} && nn `isPrev` nmLhs
-> []
(Just (ANm_Lhs dn _),Just (ANm_Lhs sn _)) | dn == sn && (isThr nmLhs nmLhs dn) && nmLhs `isPrev` nmLhs
-> []
_ -> [@self]
| * - Eqn lhs . replCrEqns = [@self]
SEM ARule
| Rule lhs . self = ARule_Rule @ndNmL @rlNm @info @eqns.replCrEqns
%%]