-----------------------------------------------------------------------------
-- Copyright 2019, Advise-Me project team. This file is distributed under 
-- the terms of the Apache License 2.0. For more information, see the files
-- "LICENSE.txt" and "NOTICE.txt", which are included in the distribution.
-----------------------------------------------------------------------------
-- |
-- Maintainer  :  bastiaan.heeren@ou.nl
-- Stability   :  provisional
-- Portability :  portable (depends on ghc)
--
-- Custom exercises used within the AdviseMe code.
--
-----------------------------------------------------------------------------

module Recognize.Strategy.Exercises where

import Domain.Math.CleanUp
import Domain.Math.Data.Relation
import Domain.Math.Equation.Views
import Domain.Math.Expr
import Domain.Math.Numeric.Views
import Domain.Math.Polynomial.BuggyRules
import Domain.Math.Polynomial.Views
import Ideas.Common.Library

import Recognize.Strategy.Strategies
import Recognize.Strategy.Views

-- | Exercise used by the strategy recognizer for recognizing linear equations.
-- This exercise uses the `recognizerStrategy` strategy and has two additional characteristics:
--
-- * Expressions are seen as equal up to 1 decimal (1.15 == 1.2)
-- * Relations are equal regardless of the relation type (a < b == a > b)
recognizerExercise :: Exercise (Relation Expr)
recognizerExercise = makeExercise
  { exerciseId    = describe "Evaluate an equation to solved form" $ newId "eval.equation.solvedform"
  , status        = Experimental
  , strategy      = recognizerStrategy
  , prettyPrinter = show
  , navigation    = termNavigator
  , ready         = predicateView relationSolvedForm
  , similarity    = withoutContext (viewEquivalent (traverseView cleanUpACView >>> approxRelView >>> relEqualityView))
  }

-- | Exercise for simplifying expressions
simplifyExercise :: Exercise Expr
simplifyExercise = makeExercise
   { exerciseId   = describe "simplify expression that may contain variables" $
                       newId "algebra.manipulation.polynomial.rational"
   , equivalence  = withoutContext (viewEquivalent (polyViewWith rationalView))
   , ready        = predicateView $ polyViewWith rationalView
   , strategy     = simplifyStrategy
   , navigation   = termNavigator
   }

-- | Exercise for normalizing expressions
normalizeExercise :: Exercise Expr
normalizeExercise = makeExercise
   { exerciseId   = describe "normalize an expressions (includes simplifying fractions)" $
                       newId "algebra.manipulation.polynomial.rational"
   , equivalence  = withoutContext (viewEquivalent (polyViewWith rationalView))
   , ready        = predicateView $ polyViewWith rationalView
   , strategy     = normalizeStrategy
   , navigation   = termNavigator
   , extraRules   = map liftToContext buggyRulesExpr
   }