packages feed

ideas-0.6: src/Common/Strategy/BiasedChoice.hs

-----------------------------------------------------------------------------
-- Copyright 2010, Open Universiteit Nederland. This file is distributed 
-- under the terms of the GNU General Public License. For more information, 
-- see the file "LICENSE.txt", which is included in the distribution.
-----------------------------------------------------------------------------
-- |
-- Maintainer  :  bastiaan.heeren@ou.nl
-- Stability   :  provisional
-- Portability :  portable (depends on ghc)
--
-----------------------------------------------------------------------------
module Common.Strategy.BiasedChoice 
   ( Bias(..), placeBiasLabels, biasTreeG, makeBiasedTree
   ) where

import Common.Apply
-- import Common.View
import Common.Derivation
import Common.Transformation
import Common.Strategy.Core
-- import Common.Uniplate

data Bias f a = TryFirst BiasId | OrElse BiasId | Normal (f a) deriving Show
type BiasId = Int

instance Apply f => Apply (Bias f) where
   applyAll (Normal r) = applyAll r
   applyAll _          = return

-- Disabled! 
placeBiasLabels :: Core l a -> Core (Either (Bias f a) l) a
placeBiasLabels = {-fst . rec 0 . -}mapLabel Right
 where {-
   -- Left-biased choice
   rec n (a :|>: b) = 
      let (ra, n1) = rec n  a
          (rb, n2) = rec n1 b
          left     = Label (Left (TryFirst n)) ra
          right    = Label (Left (OrElse n))   rb
      in (left :|: right, n2)
   -- All other cases
   rec n core = 
      let (cs, f)  = uniplate core
      in first f (recList n cs)
      
   recList n [] = ([], n)
   recList n (x:xs) = 
      let (a,  n1) = rec n x
          (as, n2) = recList n1 xs
      in (a:as, n2) -}

biasTranslation :: (Rule a -> f a) -> Translation (Either (Bias f a) l) a (Bias f a)
biasTranslation f = (either Before (const Skip), Normal . f)

biasTreeG :: (DerivationTree (f a, info) a -> Bool) -> DerivationTree (Bias f a, info) a -> DerivationTree (f a, info) a
biasTreeG success t = t {branches = f [] (branches t)}
 where
   f _ [] = []
   f env (((bias, info), st):xs) = 
      case bias of
         TryFirst n
            | success new -> branches new ++ f (n:env) xs
            | otherwise   -> f env xs
          where new = biasTreeG success st
         OrElse n   
            | n `elem` env -> f env xs
            | otherwise    -> branches (biasTreeG success st) ++ f env xs
         Normal r   -> ((r, info), biasTreeG success st):f env xs

--   success :: DerivationTree s a -> Bool
--   success = isJust . derivation

biasTree :: (DerivationTree (f a) a -> Bool) -> DerivationTree (Bias f a) a -> DerivationTree (f a) a
biasTree success t = t {branches = f [] (branches t)}
 where
   f _ [] = []
   f env ((bias, st):xs) = 
      case bias of
         TryFirst n
            | success new -> branches new ++ f (n:env) xs
            | otherwise   -> f env xs
          where new = biasTree success st
         OrElse n   
            | n `elem` env -> f env xs
            | otherwise    -> branches (biasTree success st) ++ f env xs
         Normal r   -> (r, biasTree success st):f env xs
{-
   success :: DerivationTree s a -> Bool
   success = isJust . derivation -}
   
makeBiasedTree :: (DerivationTree (Rule a) a -> Bool) -> Core l a -> a -> DerivationTree (Rule a) a
makeBiasedTree p core = 
   biasTree p . changeLabel fst . runTree (strategyTree (biasTranslation id) (placeBiasLabels core))
    
-------------------------
{-
test = makeBiasedTree (maybe False (const True) . derivation) myCore 5

myCore = (r1 :|>: r2) :|: (r3 :|>: r4)
 where
   r1 = make "r1" $ \n -> trace "**1**" [n*n]
   r2 = make "r2" $ \n -> trace "**2**" [n+1]
   r3 = make "r3" $ \n -> trace "**3**" [n*2]
   r4 = make "r4" $ \n -> trace "**4**" [n `div` 2]
   trace _ = id
   make n = Rule Nothing . minorRule . makeSimpleRuleList n -}