-- ==========================================================-- -- === Computes inverses of function applications. ===-- -- === Inverse.hs ===-- -- ==========================================================-- module Inverse where import BaseDefs import Utils import MyUtils import AbstractVals2 import SuccsAndPreds2 import AbstractMisc import Apply -- ==========================================================-- -- inMinInverse :: Bool -> Domain -> Route -> Route -> [FrontierElem] inMinInverse mindless fDomain (Rep f) res | mindless = second (inMMI_mindless fDomain f res) | otherwise = second (inMMI fDomain f res) -- ==========================================================-- -- inMaxInverse :: Bool -> Domain -> Route -> Route -> [FrontierElem] inMaxInverse mindless fDomain (Rep f) res | mindless = first (inMMI_mindless fDomain f res) | otherwise = first (inMMI fDomain f res) -- ==========================================================-- -- inMMI_mindless :: Domain -> Rep -> Route -> ([FrontierElem], [FrontierElem]) inMMI_mindless (Func dss dt) f a = let totalInverseImage = inInverse_mindless dss f a in (avMaxfrel totalInverseImage, avMinfrel totalInverseImage) -- ==========================================================-- -- inNormalise :: [FrontierElem] -> [FrontierElem] -> ([FrontierElem], [FrontierElem]) inNormalise max min = let new_max = filter (`avAboveMin1frel` min) max new_min = filter (`avBelowMax0frel` new_max) min in (new_max, new_min) -- ==========================================================-- -- inIntersect :: ([FrontierElem], [FrontierElem]) -> ([FrontierElem], [FrontierElem]) -> ([FrontierElem], [FrontierElem]) inIntersect (max1, min1) (max2, min2) = let new_max = avMaxfrel [ x `avGLBfrel` y | x <- max1, y <- max2 ] new_min = avMinfrel [ x `avLUBfrel` y | x <- min1, y <- min2 ] in inNormalise new_max new_min -- ==========================================================-- -- inMMI :: Domain -> Rep -> Route -> ([FrontierElem], [FrontierElem]) inMMI (Func dss dt) (RepTwo (Min1Max0 ar f1 f0)) Zero = (f0, if null f0 then [] else [MkFrel (map avBottomR dss)]) inMMI (Func dss Two) (RepTwo (Min1Max0 ar f1 f0)) One = (if null f1 then [] else [MkFrel (map avTopR dss)], f1) inMMI (Func dss (Lift1 dts)) (Rep1 (Min1Max0 ar lf_f1 lf_f0) hfs) Stop1 = (lf_f0, if null lf_f0 then [] else [MkFrel (map avBottomR dss)]) -- special case because this happens extremely frequently inMMI (Func dss (Lift1 [dt])) (Rep1 (Min1Max0 ar lf_f1 lf_f0) [hf]) (Up1 [r]) = let (hf_maxI, hf_minI) = inMMI (avUncurry dss dt) hf r min2 = avMinfrel [ x `avLUBfrel` y | x <- hf_minI, y <- lf_f1 ] in inNormalise hf_maxI min2 inMMI (Func dss (Lift1 dts)) (Rep1 (Min1Max0 ar lf_f1 lf_f0) hfs) (Up1 rs) = let hf_domains = map (avUncurry dss) dts hf_MMIs = myZipWith3 inMMI hf_domains hfs rs (hf_maxI, hf_minI) = foldr1 inIntersect hf_MMIs min2 = avMinfrel [ x `avLUBfrel` y | x <- hf_minI, y <- lf_f1 ] in inNormalise hf_maxI min2 -- cheat on this one, because I'm lazy inMMI (Func dss (Lift2 dts)) (Rep2 lf mf hfs) a = let isoD = Func dss (Lift1 [Lift1 dts]) isoR = Rep1 lf [Rep1 mf hfs] isoA Stop2 = Stop1 isoA Up2 = Up1 [Stop1] isoA (UpUp2 rs) = Up1 [Up1 rs] in inMMI isoD isoR (isoA a) --inMMI (DFunc dss (Cross dts), RFunc (RepCross reps)) -- (Cross dts2, Split rs) -- | dts == dts2 {-INVARIANT-} -- = let doOne n -- = inMMI (avUncurryDomain (DFunc dss (dts##n)), -- RFunc (reps##n)) (dts##n, rs##n) -- in foldr1 inIntersect (map doOne [0 .. length reps - 1]) -- ---- special case for partial applications of [... -> 2] --inMMI f@(DFunc dssf Two, RFunc (RepTwo (Min1Max0 arf f1 f0))) -- g@(DFunc dssg Two, RFunc (RepTwo (Min1Max0 arg g1 g0))) -- | arf > arg && {-INVARIANT-} -- dssg == drop (length dssf - length dssg) dssf {-INVARIANT-} -- = let (g1Max, g1Min) = inMMI g (Two, One) -- (g0Max, g0Min) = inMMI g (Two, Zero) -- fMaxs = [inPapL f fels | MkFrel fels <- g1Min] -- fMins = [inPapL f fels | MkFrel fels <- g0Max] -- iMaxs = [inMMI fn (Two, One) | fn <- fMaxs] -- iMins = [inMMI fn (Two, Zero) | fn <- fMins] -- in foldr1 inIntersect (iMaxs ++ iMins) -- --inMMI f@(DFunc dssf (Lift dtf), RFunc (RepLift lff hff)) -- g@(DFunc dssg (Lift dtg), RFunc (RepLift lfg hfg)) -- | dtf == dtg && {-INVARIANT-} -- dssg == drop (length dssf - length dssg) dssf {-INVARIANT-} -- = let lofac_f = (DFunc dssf Two, RFunc (RepTwo lff)) -- lofac_g = (DFunc dssg Two, RFunc (RepTwo lfg)) -- hifac_f = (avUncurryDomain (DFunc dssf dtf), RFunc hff) -- hifac_g = (avUncurryDomain (DFunc dssg dtg), RFunc hfg) -- in inIntersect (inMMI lofac_f lofac_g) (inMMI hifac_f hifac_g) -- --inMMI f@(DFunc dssf (Cross dtfs), RFunc (RepCross repsf)) -- g@(DFunc dssg (Cross dtgs), RFunc (RepCross repsg)) -- = let doOne n -- = inMMI (avUncurryDomain (DFunc dssf (dtfs##n)), RFunc (repsf##n)) -- (avUncurryDomain (DFunc dssg (dtgs##n)), RFunc (repsg##n)) -- in foldr1 inIntersect (map doOne [0 :: Int .. length repsf - 1]) -- otherwise, give up and call the mindless method inMMI dss f a = inMMI_mindless dss f a -- ==========================================================-- ---- --inPapL :: Point -> [Point] -> Point -- --inPapL (DFunc dss Two, RFunc (RepTwo (Min1Max0 ar f1 f0))) args -- = let argCount = length args -- argDomainAfter = revDrop argCount dss -- revDrop n = reverse . drop n . reverse -- revTake n = reverse . take n . reverse -- newf1 = sort (avMinfrel [MkFrel (revDrop argCount fel) | -- MkFrel fel <- f1, -- and (myZipWith2 avBelowEQ -- (revTake argCount fel) args)]) -- newf0 = sort (avMaxfrel [MkFrel (revDrop argCount fel) | -- MkFrel fel <- f0, -- and (myZipWith2 avBelowEQ -- args (revTake argCount fel))]) -- in (DFunc argDomainAfter Two, -- RFunc (RepTwo (Min1Max0 (ar-argCount) newf1 newf0))) -- -- ==========================================================-- -- inInverse_mindless :: [Domain] -> Rep -> Route -> [FrontierElem] inInverse_mindless argDomains f a = let isPartialApp = case a of { Rep _ -> True; _ -> False } aRep = case a of { Rep r -> r } actualArgDomains = if isPartialApp then take (amRepArity f - amRepArity aRep) argDomains else argDomains allArgs = myCartesianProduct (map amAllRoutes actualArgDomains) in [MkFrel args | args <- allArgs, apApply (Rep f) args == a] --inTrace :: Bool -> Bool --inTrace x = x -- ==========================================================-- -- === end Inverse.hs ===-- -- ==========================================================--