ideas-0.6: src/Domain/Math/DerivativeExercise.hs
{-# OPTIONS -fno-case-merge #-}
-----------------------------------------------------------------------------
-- 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 Domain.Math.DerivativeExercise where
import Common.Uniplate (universe)
import Prelude hiding (repeat, (^))
import Domain.Math.DerivativeRules
import Common.Strategy (Strategy, somewhere, (<*>), alternatives, label, LabeledStrategy, try)
import qualified Common.Strategy
import Common.Navigator
import Common.Context (Context, liftToContext)
import Common.Exercise
import Common.Transformation
import Control.Monad
import Domain.Math.Simplification
import Domain.Math.Expr
derivativeExercise :: Exercise Expr
derivativeExercise = makeExercise
{ description = "Derivative"
, exerciseCode = makeCode "math" "derivative"
, status = Experimental
, parser = parseExpr
, isReady = noDiff
, extraRules = map liftToContext derivativeRules ++ [tidyup]
, strategy = derivativeStrategy
, navigation = navigator
, examples = [ex1, ex2, ex3, ex4]
}
noDiff :: Expr -> Bool
noDiff e = null [ () | Sym s _ <- universe e, s == diffSymbol ]
derivativeStrategy :: LabeledStrategy (Context Expr)
derivativeStrategy =
label "Derivative" $
try tidyup <*> Common.Strategy.repeat (derivative <*> try tidyup)
tidyup :: Rule (Context Expr)
tidyup = liftToContext $ makeSimpleRule "Tidy-up rule" $ \old ->
let new = simplify old
in if old==new then Nothing else Just new
derivative :: Strategy (Context Expr)
derivative = somewhere $ alternatives (map liftToContext derivativeRules)
ex1, ex2, ex3 :: Expr
ex1 = diff $ lambda (Var "x") $ Var "x" ^ 2
ex2 = diff $ lambda (Var "x") $ ((1/3) :*: (x ^ fromInteger 3)) :+: (fromInteger (-3) :*: (x ^ fromInteger 2)) :+: x :+: fromInteger (-5)
where x = Var "x"
ex3 = diff $ lambda (Var "x") (2 * Var "x")
ex4 = diff $ lambda (Var "x") (ln (Var "x"))
main :: IO ()
main = forM_ [ex1, ex2, ex3, ex4] $
printDerivation derivativeExercise