-----------------------------------------------------------------------------
-- 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)
--
-- Extends the `Expr` data type by creating new symbols.
-- 
-----------------------------------------------------------------------------

module Recognize.Expr.Symbols where

import Domain.Math.Expr
import Domain.Math.Data.Relation
import Ideas.Common.Rewriting

-- | Approximates to a certain precision
approxSymbol :: Symbol
approxSymbol = newSymbol "approx"

-- | Stores a degree of precision along side the expression
approx :: Integer -> Expr -> Expr
approx p e = Sym approxSymbol [Nat p, e]

-- | Matches anything
wildcardSymbol :: Symbol
wildcardSymbol = newSymbol "wildcard"

isWildcardSymbol :: Symbol -> Bool
isWildcardSymbol = (==wildcardSymbol)

-- | Use this to match anything
--
-- Only works though if the used comparison function is aware of the symbol
wildcard :: Expr
wildcard = Sym wildcardSymbol []

wildcardRelation :: Relation Expr
wildcardRelation = wildcard .==. wildcard

-- | An identifiable wildcard
namedWildcardSymbol :: Symbol
namedWildcardSymbol = newSymbol "namedWildcard"

isNamedWildcardSymbol :: Symbol -> Bool
isNamedWildcardSymbol = (==namedWildcardSymbol)

-- Create an identifiable wildcard
namedWildcard :: String -> Expr
namedWildcard s = Sym namedWildcardSymbol [Var s]

-- | Symbol for normalizing expressions
normalformSymbol :: Symbol
normalformSymbol = newSymbol "normalform"

isNormalformSymbol :: Symbol -> Bool
isNormalformSymbol = (==normalformSymbol)

-- | The contained expression will be normalized at some point
normalform :: Expr -> Expr
normalform e = Sym normalformSymbol [e]