packages feed

egison 3.5.10 → 3.6.0

raw patch · 33 files changed

+2457/−546 lines, 33 filesPVP ok

version bump matches the API change (PVP)

API changes (from Hackage documentation)

- Language.Egison.Desugar: instance Applicative DesugarM
- Language.Egison.Desugar: instance Functor DesugarM
- Language.Egison.Desugar: instance Monad DesugarM
- Language.Egison.Desugar: instance MonadError EgisonError DesugarM
- Language.Egison.Desugar: instance MonadFresh DesugarM
- Language.Egison.Desugar: instance MonadReader Subst DesugarM
- Language.Egison.Types: ApplyPat :: EgisonExpr -> [EgisonPattern] -> EgisonPattern
- Language.Egison.Types: ArraySizeExpr :: EgisonExpr -> EgisonExpr
- Language.Egison.Types: ContExpr :: EgisonExpr
- Language.Egison.Types: Number :: (Integer, Integer) -> (Integer, Integer) -> EgisonValue
- Language.Egison.Types: NumberExpr :: (Integer, Integer) -> (Integer, Integer) -> EgisonExpr
- Language.Egison.Types: addInteger :: EgisonValue -> EgisonValue -> EgisonValue
- Language.Egison.Types: addInteger' :: (Integer, Integer) -> (Integer, Integer) -> (Integer, Integer)
- Language.Egison.Types: instance (Applicative m, Monad m) => MonadFresh (FreshT m)
- Language.Egison.Types: instance (EgisonData a, EgisonData b) => EgisonData (a, b)
- Language.Egison.Types: instance (EgisonData a, EgisonData b, EgisonData c) => EgisonData (a, b, c)
- Language.Egison.Types: instance (EgisonData a, EgisonData b, EgisonData c, EgisonData d) => EgisonData (a, b, c, d)
- Language.Egison.Types: instance (Monad m, Functor m) => Applicative (FreshT m)
- Language.Egison.Types: instance (MonadFresh m, Error e) => MonadFresh (ErrorT e m)
- Language.Egison.Types: instance (MonadFresh m, Monoid e) => MonadFresh (ReaderT e m)
- Language.Egison.Types: instance (MonadFresh m, Monoid e) => MonadFresh (WriterT e m)
- Language.Egison.Types: instance Applicative EgisonM
- Language.Egison.Types: instance EgisonData ()
- Language.Egison.Types: instance EgisonData Bool
- Language.Egison.Types: instance EgisonData Char
- Language.Egison.Types: instance EgisonData Double
- Language.Egison.Types: instance EgisonData Handle
- Language.Egison.Types: instance EgisonData Integer
- Language.Egison.Types: instance EgisonData Rational
- Language.Egison.Types: instance EgisonData Text
- Language.Egison.Types: instance EgisonData a => EgisonData [a]
- Language.Egison.Types: instance EgisonWHNF Bool
- Language.Egison.Types: instance EgisonWHNF Char
- Language.Egison.Types: instance EgisonWHNF Double
- Language.Egison.Types: instance EgisonWHNF Handle
- Language.Egison.Types: instance EgisonWHNF Integer
- Language.Egison.Types: instance EgisonWHNF Rational
- Language.Egison.Types: instance EgisonWHNF Text
- Language.Egison.Types: instance Eq EgisonValue
- Language.Egison.Types: instance Error EgisonError
- Language.Egison.Types: instance Exception EgisonError
- Language.Egison.Types: instance Functor EgisonM
- Language.Egison.Types: instance Functor m => Functor (FreshT m)
- Language.Egison.Types: instance Monad EgisonM
- Language.Egison.Types: instance Monad m => Monad (FreshT m)
- Language.Egison.Types: instance Monad m => MonadState Int (FreshT m)
- Language.Egison.Types: instance MonadError EgisonError EgisonM
- Language.Egison.Types: instance MonadError e m => MonadError e (FreshT m)
- Language.Egison.Types: instance MonadFresh EgisonM
- Language.Egison.Types: instance MonadFresh m => MonadFresh (StateT s m)
- Language.Egison.Types: instance MonadIO (FreshT IO)
- Language.Egison.Types: instance MonadIO EgisonM
- Language.Egison.Types: instance MonadState s m => MonadState s (FreshT m)
- Language.Egison.Types: instance MonadTrans FreshT
- Language.Egison.Types: instance Show (MList m a)
- Language.Egison.Types: instance Show EgisonError
- Language.Egison.Types: instance Show EgisonExpr
- Language.Egison.Types: instance Show EgisonPattern
- Language.Egison.Types: instance Show EgisonTopExpr
- Language.Egison.Types: instance Show EgisonValue
- Language.Egison.Types: instance Show InnerExpr
- Language.Egison.Types: instance Show LoopPatContext
- Language.Egison.Types: instance Show LoopRange
- Language.Egison.Types: instance Show MatchingState
- Language.Egison.Types: instance Show MatchingTree
- Language.Egison.Types: instance Show Object
- Language.Egison.Types: instance Show ObjectRef
- Language.Egison.Types: instance Show PMMode
- Language.Egison.Types: instance Show PrimitiveDataPattern
- Language.Egison.Types: instance Show PrimitivePatPattern
- Language.Egison.Types: instance Show WHNFData
- Language.Egison.Types: instance Typeable EgisonError
- Language.Egison.Types: mulInteger :: EgisonValue -> EgisonValue -> EgisonValue
- Language.Egison.Types: mulInteger' :: (Integer, Integer) -> (Integer, Integer) -> (Integer, Integer)
- Language.Egison.Types: reduceFraction :: EgisonValue -> EgisonValue
- Language.Egison.Types: subInteger :: EgisonValue -> EgisonValue -> EgisonValue
- Language.Egison.Types: subInteger' :: (Integer, Integer) -> (Integer, Integer) -> (Integer, Integer)
- Language.Egison.Types: type Env = [HashMap Var ObjectRef]
- Language.Egison.Types: unEgisonM :: EgisonM a -> ErrorT EgisonError (FreshT IO) a
- Language.Egison.Types: unFreshT :: FreshT m a -> StateT Int m a
+ Language.Egison.Core: arrayBounds :: WHNFData -> EgisonM WHNFData
+ Language.Egison.Core: collectionToList :: WHNFData -> EgisonM [EgisonValue]
+ Language.Egison.Core: refArray :: WHNFData -> [EgisonValue] -> EgisonM WHNFData
+ Language.Egison.Core: tupleToList :: WHNFData -> EgisonM [EgisonValue]
+ Language.Egison.Desugar: instance Control.Monad.Error.Class.MonadError Language.Egison.Types.EgisonError Language.Egison.Desugar.DesugarM
+ Language.Egison.Desugar: instance Control.Monad.Reader.Class.MonadReader Language.Egison.Desugar.Subst Language.Egison.Desugar.DesugarM
+ Language.Egison.Desugar: instance GHC.Base.Applicative Language.Egison.Desugar.DesugarM
+ Language.Egison.Desugar: instance GHC.Base.Functor Language.Egison.Desugar.DesugarM
+ Language.Egison.Desugar: instance GHC.Base.Monad Language.Egison.Desugar.DesugarM
+ Language.Egison.Desugar: instance Language.Egison.Types.MonadFresh Language.Egison.Desugar.DesugarM
+ Language.Egison.Types: Apply :: EgisonValue -> [ScalarData] -> SymbolExpr
+ Language.Egison.Types: ArrayBoundsExpr :: EgisonExpr -> EgisonExpr
+ Language.Egison.Types: CApplyExpr :: EgisonExpr -> EgisonExpr -> EgisonExpr
+ Language.Egison.Types: CFunc :: (Maybe String) -> Env -> String -> EgisonExpr -> EgisonValue
+ Language.Egison.Types: CambdaExpr :: String -> EgisonExpr -> EgisonExpr
+ Language.Egison.Types: DApplyPat :: EgisonPattern -> [EgisonPattern] -> EgisonPattern
+ Language.Egison.Types: Div :: PolyExpr -> PolyExpr -> ScalarData
+ Language.Egison.Types: Env :: [HashMap Var ObjectRef] -> Env
+ Language.Egison.Types: GenerateTensorExpr :: EgisonExpr -> EgisonExpr -> EgisonExpr
+ Language.Egison.Types: InconsistentTensorIndex :: EgisonError
+ Language.Egison.Types: InconsistentTensorSize :: EgisonError
+ Language.Egison.Types: InitTensorExpr :: EgisonExpr -> EgisonExpr -> EgisonExpr -> EgisonExpr
+ Language.Egison.Types: IntegerExpr :: Integer -> EgisonExpr
+ Language.Egison.Types: Macro :: [String] -> EgisonExpr -> EgisonValue
+ Language.Egison.Types: MacroExpr :: [String] -> EgisonExpr -> EgisonExpr
+ Language.Egison.Types: PApplyPat :: EgisonExpr -> [EgisonPattern] -> EgisonPattern
+ Language.Egison.Types: PDTuplePat :: [PrimitiveDataPattern] -> PrimitiveDataPattern
+ Language.Egison.Types: Plus :: [TermExpr] -> PolyExpr
+ Language.Egison.Types: PowerExpr :: EgisonExpr -> EgisonExpr -> EgisonExpr
+ Language.Egison.Types: ScalarData :: ScalarData -> EgisonValue
+ Language.Egison.Types: Symbol :: String -> [Integer] -> SymbolExpr
+ Language.Egison.Types: TData :: (Tensor ScalarData) -> (Maybe [ScalarData]) -> TensorData
+ Language.Egison.Types: Tensor :: [Integer] -> [a] -> Tensor a
+ Language.Egison.Types: TensorData :: TensorData -> EgisonValue
+ Language.Egison.Types: TensorExpr :: EgisonExpr -> EgisonExpr -> EgisonExpr
+ Language.Egison.Types: TensorIndexOutOfBounds :: Integer -> Integer -> EgisonError
+ Language.Egison.Types: TensorMap2Expr :: EgisonExpr -> EgisonExpr -> EgisonExpr -> EgisonExpr
+ Language.Egison.Types: TensorMapExpr :: EgisonExpr -> EgisonExpr -> EgisonExpr
+ Language.Egison.Types: Term :: Integer -> [(SymbolExpr, Integer)] -> TermExpr
+ Language.Egison.Types: [unEgisonM] :: EgisonM a -> ErrorT EgisonError (FreshT IO) a
+ Language.Egison.Types: [unFreshT] :: FreshT m a -> StateT Int m a
+ Language.Egison.Types: data Env
+ Language.Egison.Types: data PolyExpr
+ Language.Egison.Types: data ScalarData
+ Language.Egison.Types: data SymbolExpr
+ Language.Egison.Types: data Tensor a
+ Language.Egison.Types: data TensorData
+ Language.Egison.Types: data TermExpr
+ Language.Egison.Types: egisonToScalarData :: EgisonValue -> EgisonM ScalarData
+ Language.Egison.Types: instance (GHC.Base.Applicative m, GHC.Base.Monad m) => Language.Egison.Types.MonadFresh (Language.Egison.Types.FreshT m)
+ Language.Egison.Types: instance (Language.Egison.Types.EgisonData a, Language.Egison.Types.EgisonData b) => Language.Egison.Types.EgisonData (a, b)
+ Language.Egison.Types: instance (Language.Egison.Types.EgisonData a, Language.Egison.Types.EgisonData b, Language.Egison.Types.EgisonData c) => Language.Egison.Types.EgisonData (a, b, c)
+ Language.Egison.Types: instance (Language.Egison.Types.EgisonData a, Language.Egison.Types.EgisonData b, Language.Egison.Types.EgisonData c, Language.Egison.Types.EgisonData d) => Language.Egison.Types.EgisonData (a, b, c, d)
+ Language.Egison.Types: instance (Language.Egison.Types.MonadFresh m, Control.Monad.Trans.Error.Error e) => Language.Egison.Types.MonadFresh (Control.Monad.Trans.Error.ErrorT e m)
+ Language.Egison.Types: instance (Language.Egison.Types.MonadFresh m, GHC.Base.Monoid e) => Language.Egison.Types.MonadFresh (Control.Monad.Trans.Reader.ReaderT e m)
+ Language.Egison.Types: instance (Language.Egison.Types.MonadFresh m, GHC.Base.Monoid e) => Language.Egison.Types.MonadFresh (Control.Monad.Trans.Writer.Lazy.WriterT e m)
+ Language.Egison.Types: instance Control.Monad.Error.Class.MonadError Language.Egison.Types.EgisonError Language.Egison.Types.EgisonM
+ Language.Egison.Types: instance Control.Monad.Error.Class.MonadError e m => Control.Monad.Error.Class.MonadError e (Language.Egison.Types.FreshT m)
+ Language.Egison.Types: instance Control.Monad.IO.Class.MonadIO (Language.Egison.Types.FreshT GHC.Types.IO)
+ Language.Egison.Types: instance Control.Monad.IO.Class.MonadIO Language.Egison.Types.EgisonM
+ Language.Egison.Types: instance Control.Monad.State.Class.MonadState s m => Control.Monad.State.Class.MonadState s (Language.Egison.Types.FreshT m)
+ Language.Egison.Types: instance Control.Monad.Trans.Class.MonadTrans Language.Egison.Types.FreshT
+ Language.Egison.Types: instance Control.Monad.Trans.Error.Error Language.Egison.Types.EgisonError
+ Language.Egison.Types: instance GHC.Base.Applicative Language.Egison.Types.EgisonM
+ Language.Egison.Types: instance GHC.Base.Functor Language.Egison.Types.EgisonM
+ Language.Egison.Types: instance GHC.Base.Functor m => GHC.Base.Functor (Language.Egison.Types.FreshT m)
+ Language.Egison.Types: instance GHC.Base.Monad Language.Egison.Types.EgisonM
+ Language.Egison.Types: instance GHC.Base.Monad m => Control.Monad.State.Class.MonadState GHC.Types.Int (Language.Egison.Types.FreshT m)
+ Language.Egison.Types: instance GHC.Base.Monad m => GHC.Base.Applicative (Language.Egison.Types.FreshT m)
+ Language.Egison.Types: instance GHC.Base.Monad m => GHC.Base.Monad (Language.Egison.Types.FreshT m)
+ Language.Egison.Types: instance GHC.Classes.Eq Language.Egison.Types.EgisonExpr
+ Language.Egison.Types: instance GHC.Classes.Eq Language.Egison.Types.EgisonPattern
+ Language.Egison.Types: instance GHC.Classes.Eq Language.Egison.Types.EgisonTopExpr
+ Language.Egison.Types: instance GHC.Classes.Eq Language.Egison.Types.EgisonValue
+ Language.Egison.Types: instance GHC.Classes.Eq Language.Egison.Types.InnerExpr
+ Language.Egison.Types: instance GHC.Classes.Eq Language.Egison.Types.LoopRange
+ Language.Egison.Types: instance GHC.Classes.Eq Language.Egison.Types.PolyExpr
+ Language.Egison.Types: instance GHC.Classes.Eq Language.Egison.Types.PrimitiveDataPattern
+ Language.Egison.Types: instance GHC.Classes.Eq Language.Egison.Types.PrimitivePatPattern
+ Language.Egison.Types: instance GHC.Classes.Eq Language.Egison.Types.ScalarData
+ Language.Egison.Types: instance GHC.Classes.Eq Language.Egison.Types.SymbolExpr
+ Language.Egison.Types: instance GHC.Classes.Eq Language.Egison.Types.TensorData
+ Language.Egison.Types: instance GHC.Classes.Eq Language.Egison.Types.TermExpr
+ Language.Egison.Types: instance GHC.Classes.Eq a => GHC.Classes.Eq (Language.Egison.Types.Tensor a)
+ Language.Egison.Types: instance GHC.Exception.Exception Language.Egison.Types.EgisonError
+ Language.Egison.Types: instance GHC.Show.Show (Language.Egison.Types.MList m a)
+ Language.Egison.Types: instance GHC.Show.Show (Language.Egison.Types.Tensor Language.Egison.Types.ScalarData)
+ Language.Egison.Types: instance GHC.Show.Show Language.Egison.Types.EgisonError
+ Language.Egison.Types: instance GHC.Show.Show Language.Egison.Types.EgisonExpr
+ Language.Egison.Types: instance GHC.Show.Show Language.Egison.Types.EgisonPattern
+ Language.Egison.Types: instance GHC.Show.Show Language.Egison.Types.EgisonTopExpr
+ Language.Egison.Types: instance GHC.Show.Show Language.Egison.Types.EgisonValue
+ Language.Egison.Types: instance GHC.Show.Show Language.Egison.Types.Env
+ Language.Egison.Types: instance GHC.Show.Show Language.Egison.Types.InnerExpr
+ Language.Egison.Types: instance GHC.Show.Show Language.Egison.Types.LoopPatContext
+ Language.Egison.Types: instance GHC.Show.Show Language.Egison.Types.LoopRange
+ Language.Egison.Types: instance GHC.Show.Show Language.Egison.Types.MatchingState
+ Language.Egison.Types: instance GHC.Show.Show Language.Egison.Types.MatchingTree
+ Language.Egison.Types: instance GHC.Show.Show Language.Egison.Types.Object
+ Language.Egison.Types: instance GHC.Show.Show Language.Egison.Types.ObjectRef
+ Language.Egison.Types: instance GHC.Show.Show Language.Egison.Types.PMMode
+ Language.Egison.Types: instance GHC.Show.Show Language.Egison.Types.PolyExpr
+ Language.Egison.Types: instance GHC.Show.Show Language.Egison.Types.PrimitiveDataPattern
+ Language.Egison.Types: instance GHC.Show.Show Language.Egison.Types.PrimitivePatPattern
+ Language.Egison.Types: instance GHC.Show.Show Language.Egison.Types.ScalarData
+ Language.Egison.Types: instance GHC.Show.Show Language.Egison.Types.SymbolExpr
+ Language.Egison.Types: instance GHC.Show.Show Language.Egison.Types.TensorData
+ Language.Egison.Types: instance GHC.Show.Show Language.Egison.Types.TermExpr
+ Language.Egison.Types: instance GHC.Show.Show Language.Egison.Types.WHNFData
+ Language.Egison.Types: instance Language.Egison.Types.EgisonData ()
+ Language.Egison.Types: instance Language.Egison.Types.EgisonData Data.Text.Internal.Text
+ Language.Egison.Types: instance Language.Egison.Types.EgisonData GHC.IO.Handle.Types.Handle
+ Language.Egison.Types: instance Language.Egison.Types.EgisonData GHC.Integer.Type.Integer
+ Language.Egison.Types: instance Language.Egison.Types.EgisonData GHC.Real.Rational
+ Language.Egison.Types: instance Language.Egison.Types.EgisonData GHC.Types.Bool
+ Language.Egison.Types: instance Language.Egison.Types.EgisonData GHC.Types.Char
+ Language.Egison.Types: instance Language.Egison.Types.EgisonData GHC.Types.Double
+ Language.Egison.Types: instance Language.Egison.Types.EgisonData a => Language.Egison.Types.EgisonData [a]
+ Language.Egison.Types: instance Language.Egison.Types.EgisonWHNF Data.Text.Internal.Text
+ Language.Egison.Types: instance Language.Egison.Types.EgisonWHNF GHC.IO.Handle.Types.Handle
+ Language.Egison.Types: instance Language.Egison.Types.EgisonWHNF GHC.Integer.Type.Integer
+ Language.Egison.Types: instance Language.Egison.Types.EgisonWHNF GHC.Types.Bool
+ Language.Egison.Types: instance Language.Egison.Types.EgisonWHNF GHC.Types.Char
+ Language.Egison.Types: instance Language.Egison.Types.EgisonWHNF GHC.Types.Double
+ Language.Egison.Types: instance Language.Egison.Types.MonadFresh Language.Egison.Types.EgisonM
+ Language.Egison.Types: instance Language.Egison.Types.MonadFresh m => Language.Egison.Types.MonadFresh (Control.Monad.Trans.State.Lazy.StateT s m)
+ Language.Egison.Types: isArray' :: PrimitiveFunc
+ Language.Egison.Types: isBool :: EgisonValue -> Bool
+ Language.Egison.Types: isBool' :: PrimitiveFunc
+ Language.Egison.Types: isChar' :: PrimitiveFunc
+ Language.Egison.Types: isCollection' :: PrimitiveFunc
+ Language.Egison.Types: isComplex' :: PrimitiveFunc
+ Language.Egison.Types: isFloat' :: PrimitiveFunc
+ Language.Egison.Types: isHash' :: PrimitiveFunc
+ Language.Egison.Types: isInteger :: EgisonValue -> Bool
+ Language.Egison.Types: isInteger' :: PrimitiveFunc
+ Language.Egison.Types: isNumber :: EgisonValue -> Bool
+ Language.Egison.Types: isNumber' :: PrimitiveFunc
+ Language.Egison.Types: isRational :: EgisonValue -> Bool
+ Language.Egison.Types: isRational' :: PrimitiveFunc
+ Language.Egison.Types: isString' :: PrimitiveFunc
+ Language.Egison.Types: isSymbol :: EgisonValue -> Bool
+ Language.Egison.Types: isTensor :: EgisonValue -> Bool
+ Language.Egison.Types: isTensor' :: PrimitiveFunc
+ Language.Egison.Types: isTensorWithIndex :: EgisonValue -> Bool
+ Language.Egison.Types: isTensorWithIndex' :: PrimitiveFunc
+ Language.Egison.Types: makeTensor :: [Integer] -> [ScalarData] -> (Maybe [ScalarData]) -> TensorData
+ Language.Egison.Types: mathDenominator :: ScalarData -> ScalarData
+ Language.Egison.Types: mathExprToEgison :: ScalarData -> EgisonValue
+ Language.Egison.Types: mathFold :: ScalarData -> ScalarData
+ Language.Egison.Types: mathMult :: ScalarData -> ScalarData -> ScalarData
+ Language.Egison.Types: mathNegate :: ScalarData -> ScalarData
+ Language.Egison.Types: mathNormalize' :: ScalarData -> ScalarData
+ Language.Egison.Types: mathNumerator :: ScalarData -> ScalarData
+ Language.Egison.Types: mathPlus :: ScalarData -> ScalarData -> ScalarData
+ Language.Egison.Types: mathReduceFraction :: ScalarData -> ScalarData
+ Language.Egison.Types: mathReduceSymbolFraction :: ScalarData -> ScalarData
+ Language.Egison.Types: mathRemoveZero :: ScalarData -> ScalarData
+ Language.Egison.Types: mathSymbolFold :: ScalarData -> ScalarData
+ Language.Egison.Types: mathTermFold :: ScalarData -> ScalarData
+ Language.Egison.Types: scalarToTensor :: [Integer] -> ScalarData -> (Maybe [ScalarData]) -> TensorData
+ Language.Egison.Types: scalarToUnitTensor :: [Integer] -> ScalarData -> (Maybe [ScalarData]) -> TensorData
+ Language.Egison.Types: symbolScalarData :: String -> [Integer] -> EgisonValue
+ Language.Egison.Types: tCheckIndex :: [ScalarData] -> [Integer] -> EgisonM ()
+ Language.Egison.Types: tContract :: TensorData -> EgisonM EgisonValue
+ Language.Egison.Types: tIndex :: TensorData -> Maybe [ScalarData]
+ Language.Egison.Types: tMap :: (ScalarData -> EgisonM ScalarData) -> TensorData -> EgisonM TensorData
+ Language.Egison.Types: tMap2 :: (ScalarData -> ScalarData -> EgisonM ScalarData) -> TensorData -> TensorData -> EgisonM TensorData
+ Language.Egison.Types: tSize :: TensorData -> [Integer]
+ Language.Egison.Types: tToList :: (Tensor a) -> [a]
+ Language.Egison.Types: tensorIndices :: [Integer] -> [[Integer]]
+ Language.Egison.Types: tref :: [ScalarData] -> (Tensor a) -> (Tensor a)
+ Language.Egison.Types: tref' :: [Integer] -> (Tensor a) -> a
- Language.Egison.Core: applyFunc :: WHNFData -> WHNFData -> EgisonM WHNFData
+ Language.Egison.Core: applyFunc :: Env -> WHNFData -> WHNFData -> EgisonM WHNFData
- Language.Egison.Types: Func :: Env -> [String] -> EgisonExpr -> EgisonValue
+ Language.Egison.Types: Func :: (Maybe String) -> Env -> [String] -> EgisonExpr -> EgisonValue
- Language.Egison.Types: GenerateArrayExpr :: [String] -> EgisonExpr -> EgisonExpr -> EgisonExpr
+ Language.Egison.Types: GenerateArrayExpr :: EgisonExpr -> (EgisonExpr, EgisonExpr) -> EgisonExpr
- Language.Egison.Types: MemoizedFunc :: ObjectRef -> (IORef (HashMap [Integer] ObjectRef)) -> Env -> [String] -> EgisonExpr -> EgisonValue
+ Language.Egison.Types: MemoizedFunc :: (Maybe String) -> ObjectRef -> (IORef (HashMap [Integer] ObjectRef)) -> Env -> [String] -> EgisonExpr -> EgisonValue
- Language.Egison.Types: PrimitiveFunc :: PrimitiveFunc -> EgisonValue
+ Language.Egison.Types: PrimitiveFunc :: String -> PrimitiveFunc -> EgisonValue
- Language.Egison.Types: class EgisonData a => EgisonWHNF a where toWHNF = Value . toEgison
+ Language.Egison.Types: class (EgisonData a) => EgisonWHNF a where toWHNF = Value . toEgison
- Language.Egison.Types: liftError :: MonadError e m => Either e a -> m a
+ Language.Egison.Types: liftError :: (MonadError e m) => Either e a -> m a
- Language.Egison.Types: refVar :: Env -> Var -> EgisonM ObjectRef
+ Language.Egison.Types: refVar :: Env -> Var -> Maybe ObjectRef

Files

LICENSE view
@@ -1,4 +1,4 @@-Copyright (c) 2011-2015, Satoshi Egi+Copyright (c) 2011-2016, Satoshi Egi  Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"),
egison.cabal view
@@ -1,5 +1,5 @@ Name:                egison-Version:             3.5.10+Version:             3.6.0 Synopsis:            Programming language with non-linear pattern-matching against non-free data Description:   An interpreter for Egison, a **pattern-matching-oriented**, purely functional programming language.@@ -59,7 +59,7 @@  Extra-Source-Files:  benchmark/Benchmark.hs -Data-files:          lib/core/*.egi+Data-files:          lib/core/*.egi lib/math/*.egi lib/math/common/*.egi lib/math/algebra/*.egi lib/math/analysis/*.egi                      sample/*.egi sample/io/*.egi                      elisp/egison-mode.el 
elisp/egison-mode.el view
@@ -48,14 +48,16 @@      "\\<lambda\\>"      "\\<memoized-lambda\\>"      "\\<memoize\\>"+     "\\<cambda\\>"+     "\\<macro\\>"      "\\<let\\>"      "\\<letrec\\>"      "\\<let\\*\\>"      "\\<if\\>"      "\\<seq\\>"-     "\\<apply\\>"+;     "\\<apply\\>"      "\\<generate-array\\>"-     "\\<array-size\\>"+     "\\<array-bounds\\>"      "\\<array-ref\\>"       "\\<loop\\>"@@ -88,6 +90,7 @@      "|"      "\\\&"      "@"+     "!"      "\\<_\\>"       "\\<assert\\>"@@ -170,6 +173,8 @@         ((equal "load-file" name) 2)         ((equal "execute" name) 2)         ((equal "lambda" name) 2)+        ((equal "cambda" name) 2)+        ((equal "macro" name) 2)         ((equal "memoized-lambda" name) 2)         ((equal "memoize" name) 2)         ((equal "letrec" name) 2)
hs-src/Interpreter/egison.hs view
@@ -216,7 +216,7 @@  showBanner :: IO () showBanner = do-  putStrLn $ "Egison Version " ++ showVersion version ++ " (C) 2011-2015 Satoshi Egi"+  putStrLn $ "Egison Version " ++ showVersion version ++ " (C) 2011-2016 Satoshi Egi"   putStrLn $ "http://www.egison.org"   putStrLn $ "Welcome to Egison Interpreter!" --  putStrLn $ "** Information **"
hs-src/Language/Egison.hs view
@@ -105,12 +105,22 @@  coreLibraries :: [String] coreLibraries =-  [ "lib/core/base.egi"+  [ "lib/math/expression.egi"+  , "lib/math/normalize.egi"+  , "lib/math/common/arithmetic.egi"+  , "lib/math/common/functions.egi"+  , "lib/math/algebra/root.egi"+  , "lib/math/algebra/equations.egi"+  , "lib/math/algebra/inverse.egi"+  , "lib/math/analysis/derivative.egi"+  , "lib/math/analysis/integral.egi"+  , "lib/math/algebra/tensor.egi"+  , "lib/core/base.egi"   , "lib/core/collection.egi"+  , "lib/core/assoc.egi"   , "lib/core/order.egi"   , "lib/core/number.egi"   , "lib/core/io.egi"   , "lib/core/random.egi"-  , "lib/core/array.egi"   , "lib/core/string.egi"   ]
hs-src/Language/Egison/Core.hs view
@@ -21,6 +21,9 @@     , evalRefDeep     , evalWHNF     , applyFunc+    -- * Array+    , refArray+    , arrayBounds     -- * Environment     , recursiveBind     -- * Pattern matching@@ -29,6 +32,9 @@     , isEmptyCollection     , unconsCollection     , unsnocCollection+    -- * Tuple, Collection+    , tupleToList+    , collectionToList     -- * Utiltiy functions     , packStringValue     ) where@@ -49,9 +55,11 @@ import Data.IORef import Data.Maybe +import qualified Data.HashMap.Lazy as HL import Data.Array ((!)) import qualified Data.Array as Array-import qualified Data.HashMap.Lazy as HL+import Data.HashMap.Strict (HashMap)+import qualified Data.HashMap.Strict as HashMap  import Data.Text (Text) import qualified Data.Text as T@@ -70,6 +78,7 @@   forM_ rest $ evalTopExpr env   return env  where+  collectDefs :: [EgisonTopExpr] -> [(String, EgisonExpr)] -> [EgisonTopExpr] -> EgisonM ([(String, EgisonExpr)], [EgisonTopExpr])   collectDefs (expr:exprs) bindings rest =     case expr of       Define name expr -> collectDefs exprs ((name, expr) : bindings) rest@@ -90,6 +99,7 @@   forM_ rest $ evalTopExpr env   return env  where+  collectDefs :: [EgisonTopExpr] -> [(String, EgisonExpr)] -> [EgisonTopExpr] -> EgisonM ([(String, EgisonExpr)], [EgisonTopExpr])   collectDefs (expr:exprs) bindings rest =     case expr of       Define name expr -> collectDefs exprs ((name, expr) : bindings) rest@@ -110,6 +120,7 @@   forM_ rest $ evalTopExpr env   return env  where+  collectDefs :: [EgisonTopExpr] -> [(String, EgisonExpr)] -> [EgisonTopExpr] -> EgisonM ([(String, EgisonExpr)], [EgisonTopExpr])   collectDefs (expr:exprs) bindings rest =     case expr of       Define name expr -> collectDefs exprs ((name, expr) : bindings) rest@@ -143,10 +154,14 @@ evalExpr _ (CharExpr c) = return . Value $ Char c evalExpr _ (StringExpr s) = return $ Value $ toEgison s evalExpr _ (BoolExpr b) = return . Value $ Bool b-evalExpr _ (NumberExpr x y) = return . Value $ reduceFraction (Number x y)+evalExpr _ (IntegerExpr x) = return . Value $ toEgison x evalExpr _ (FloatExpr x y) = return . Value $ Float x y -evalExpr env (VarExpr name) = refVar env name >>= evalRef+evalExpr env (VarExpr name) = refVar' env name >>= evalRef+ where+  refVar' :: Env -> Var -> EgisonM ObjectRef+  refVar' env var = maybe (newEvalutedObjectRef (Value (symbolScalarData var []))) return+                          (refVar env var)  evalExpr _ (InductiveDataExpr name []) = return . Value $ InductiveData name [] evalExpr env (InductiveDataExpr name exprs) =@@ -171,6 +186,34 @@   refs' <- mapM (newObjectRef env) exprs   return . Intermediate . IArray $ Array.listArray (1, toInteger (length exprs)) refs' +evalExpr env (TensorExpr nsExpr xsExpr) = do+  nsWhnf <- evalExpr env nsExpr+  ns <- ((fromCollection nsWhnf >>= fromMList >>= mapM evalRef >>= mapM fromWHNF) :: EgisonM [Integer])+  xsWhnf <- evalExpr env xsExpr+  xs <- fromCollection xsWhnf >>= fromMList >>= mapM evalRef >>= mapM toScalarData+  if product ns == toInteger (length xs)+    then return $ Value $ TensorData (makeTensor ns xs Nothing)+    else throwError $ InconsistentTensorSize+ where+  toScalarData :: WHNFData -> EgisonM ScalarData+  toScalarData (Value (ScalarData x)) = return x+  toScalarData val = throwError $ TypeMismatch "integer or string" $ val++evalExpr env (InitTensorExpr nsExpr xsExpr jsExpr) = do+  nsWhnf <- evalExpr env nsExpr+  ns <- ((fromCollection nsWhnf >>= fromMList >>= mapM evalRef >>= mapM fromWHNF) :: EgisonM [Integer])+  xsWhnf <- evalExpr env xsExpr+  xs <- fromCollection xsWhnf >>= fromMList >>= mapM evalRef >>= mapM toScalarData+  jsWhnf <- evalExpr env jsExpr+  js <- fromCollection jsWhnf >>= fromMList >>= mapM evalRef >>= mapM toScalarData+  if product ns == toInteger (length xs)+    then return $ Value $ TensorData (makeTensor ns xs (Just js))+    else throwError $ InconsistentTensorSize+ where+  toScalarData :: WHNFData -> EgisonM ScalarData+  toScalarData (Value (ScalarData x)) = return x+  toScalarData val = throwError $ TypeMismatch "integer or string" $ val+ evalExpr env (HashExpr assocs) = do   let (keyExprs, exprs) = unzip assocs   keyWhnfs <- mapM (evalExpr env) keyExprs@@ -195,19 +238,39 @@   makeHashKey :: WHNFData -> EgisonM EgisonHashKey   makeHashKey (Value val) =     case val of-      Number _ _ -> fromEgison val >>= (return . IntKey)+      ScalarData _ -> fromEgison val >>= (return . IntKey)       Char c -> return (CharKey c)       String str -> return (StrKey str)       _ -> throwError $ TypeMismatch "integer or string" $ Value val   makeHashKey whnf = throwError $ TypeMismatch "integer or string" $ whnf  evalExpr env (IndexedExpr expr indices) = do-  array <- evalExpr env expr+  tensor <- evalExpr env expr   indices' <- mapM (evalExprDeep env) indices-  refArray array indices'+  case tensor of+    (Value (ScalarData (Div (Plus [(Term 1 [(Symbol name [], 1)])]) (Plus [(Term 1 [])])))) -> do+      js <- (mapM fromEgison indices') :: EgisonM [Integer]+      return $ Value (ScalarData (Div (Plus [(Term 1 [(Symbol name js, 1)])]) (Plus [(Term 1 [])])))+    (Value (TensorData (TData (Tensor ns xs) _))) -> do+      indices'' <- mapM extract indices'+      tCheckIndex indices'' ns+      if all (\x -> isInteger x) indices'+        then do indices'' <- ((mapM fromEgison indices') :: EgisonM [Integer])+                return $ Value $ ScalarData (tref' indices'' (Tensor ns xs))+        else do ret <- tContract (TData (tref indices'' (Tensor ns xs)) (Just (filter (isSymbol . ScalarData) indices'')))+                return $ Value ret+    _ -> refArray tensor indices'+ where+  extract :: EgisonValue -> EgisonM ScalarData+  extract (ScalarData s) = return s+  extract val = throwError $ TypeMismatch "scalar expression" (Value val) -evalExpr env (LambdaExpr names expr) = return . Value $ Func env names expr+evalExpr env (LambdaExpr names expr) = return . Value $ Func Nothing env names expr +evalExpr env (CambdaExpr name expr) = return . Value $ CFunc Nothing env name expr++evalExpr env (MacroExpr names expr) = return . Value $ Macro names expr+ evalExpr env (PatternFunctionExpr names pattern) = return . Value $ PatternFunc env names pattern  evalExpr env (IfExpr test expr expr') = do@@ -245,7 +308,7 @@  evalExpr env (DoExpr bindings expr) = return $ Value $ IOFunc $ do   let body = foldr genLet (ApplyExpr expr $ TupleExpr [VarExpr "#1"]) bindings-  applyFunc (Value $ Func env ["#1"] body) $ Value World+  applyFunc env (Value $ Func Nothing env ["#1"] body) $ Value World  where   genLet (names, expr) expr' =     LetExpr [(["#1", "#2"], ApplyExpr expr $ TupleExpr [VarExpr "#1"])] $@@ -288,11 +351,30 @@   evalExprDeep env expr1   evalExpr env expr2 +evalExpr env (CApplyExpr func arg) = do+  func <- evalExpr env func+  args <- evalExpr env arg >>= collectionToList+  case func of+    Value (MemoizedFunc name ref hashRef env names body) -> do+      indices' <- mapM fromEgison args+      hash <- liftIO $ readIORef hashRef+      case HL.lookup indices' hash of+        Just objRef -> do+          evalRef objRef+        Nothing -> do+          whnf <- applyFunc env (Value (Func Nothing env names body)) (Value (makeTuple args))+          retRef <- newEvalutedObjectRef whnf+          hash <- liftIO $ readIORef hashRef+          liftIO $ writeIORef hashRef (HL.insert indices' retRef hash)+          writeObjectRef ref (Value (MemoizedFunc name ref hashRef env names body))+          return whnf+    _ -> applyFunc env func (Value (makeTuple args))+ evalExpr env (ApplyExpr func arg) = do   func <- evalExpr env func   arg <- evalExpr env arg   case func of-    Value (MemoizedFunc ref hashRef env names body) -> do+    Value (MemoizedFunc name ref hashRef env names body) -> do       indices <- evalWHNF arg       indices' <- mapM fromEgison $ fromTupleValue indices       hash <- liftIO $ readIORef hashRef@@ -300,25 +382,25 @@         Just objRef -> do           evalRef objRef         Nothing -> do-          whnf <- applyFunc (Value (Func env names body)) arg+          whnf <- applyFunc env (Value (Func Nothing env names body)) arg           retRef <- newEvalutedObjectRef whnf           hash <- liftIO $ readIORef hashRef           liftIO $ writeIORef hashRef (HL.insert indices' retRef hash)-          writeObjectRef ref (Value (MemoizedFunc ref hashRef env names body))+          writeObjectRef ref (Value (MemoizedFunc name ref hashRef env names body))           return whnf-    _ -> applyFunc func arg+    _ -> applyFunc env func arg  evalExpr env (MemoizeExpr memoizeFrame expr) = do   mapM (\(x, y, z) -> do x' <- evalExprDeep env x                          case x' of-                           (MemoizedFunc ref hashRef env' names body) -> do+                           (MemoizedFunc name ref hashRef env' names body) -> do                              indices <- evalExprDeep env y                              indices' <- mapM fromEgison $ fromTupleValue indices                              hash <- liftIO $ readIORef hashRef                              ret <- evalExprDeep env z                              retRef <- newEvalutedObjectRef (Value ret)                              liftIO $ writeIORef hashRef (HL.insert indices' retRef hash)-                             writeObjectRef ref (Value (MemoizedFunc ref hashRef env' names body))+                             writeObjectRef ref (Value (MemoizedFunc name ref hashRef env' names body))                            _ -> throwError $ TypeMismatch "memoized-function" (Value x'))        memoizeFrame   evalExpr env expr@@ -326,21 +408,57 @@ evalExpr env (MatcherBFSExpr info) = return $ Value $ UserMatcher env BFSMode info evalExpr env (MatcherDFSExpr info) = return $ Value $ UserMatcher env DFSMode info -evalExpr env (GenerateArrayExpr (name:[]) (TupleExpr (sizeExpr:[])) expr) =-  generateArray env name sizeExpr expr-evalExpr env (GenerateArrayExpr (name:xs) (TupleExpr (sizeExpr:ys)) expr) = -  generateArray env name sizeExpr (GenerateArrayExpr xs (TupleExpr ys) expr)-evalExpr env (GenerateArrayExpr names size expr) = -  evalExpr env (GenerateArrayExpr names (TupleExpr [size]) expr)+evalExpr env (GenerateArrayExpr fnExpr (fstExpr, lstExpr)) = do+  fN <- (evalExpr env fstExpr >>= fromWHNF) :: EgisonM Integer+  eN <- (evalExpr env lstExpr >>= fromWHNF) :: EgisonM Integer+  xs <- mapM (\n -> (newObjectRef env (ApplyExpr fnExpr (IntegerExpr n)))) [fN..eN]+  return $ Intermediate $ IArray $ Array.listArray (fN, eN) xs -evalExpr env (ArraySizeExpr expr) = -  evalExpr env expr >>= arraySize-  where-    arraySize :: WHNFData -> EgisonM WHNFData-    arraySize (Intermediate (IArray arr)) = return . Value . toEgison $ (snd (Array.bounds arr)) % 1-    arraySize (Value (Array arr))         = return . Value . toEgison $ (snd (Array.bounds arr)) % 1-    arraySize val                         = throwError $ TypeMismatch "array" val+evalExpr env (ArrayBoundsExpr expr) = +  evalExpr env expr >>= arrayBounds +evalExpr env (GenerateTensorExpr fnExpr sizeExpr) = do+  size' <- evalExpr env sizeExpr+  size'' <- collectionToList size'+  ns <- (mapM fromEgison size'') :: EgisonM [Integer]+  fn <- evalExpr env fnExpr+  xs <-  mapM (\ms -> applyFunc env fn (Value (makeTuple ms)) >>= evalWHNF >>= extractScalar) (map (\ms -> map toEgison ms) (tensorIndices ns))+  return $ Value (TensorData (makeTensor ns xs Nothing))+ where+  extractScalar :: EgisonValue -> EgisonM ScalarData+  extractScalar (ScalarData x) = return x+  extractScalar x = throwError $ TypeMismatch "scalar expression" (Value x)++evalExpr env (TensorMapExpr fnExpr tExpr) = do+  fn <- evalExpr env fnExpr+  tVal <- evalExpr env tExpr+  case tVal of+    Value (TensorData t) -> do+      tMap (applyScalarFunc env fn) t >>= (return . Value . TensorData)+    _ -> throwError $ TypeMismatch "tensor" tVal+ where+  applyScalarFunc :: Env -> WHNFData -> ScalarData -> EgisonM ScalarData+  applyScalarFunc env fn s = applyFunc env fn (Value (ScalarData s)) >>= extractScalar+  extractScalar :: WHNFData -> EgisonM ScalarData+  extractScalar (Value (ScalarData x)) = return x+  extractScalar x = throwError $ TypeMismatch "scalar expression" x++evalExpr env (TensorMap2Expr fnExpr t1Expr t2Expr) = do+  fn <- evalExpr env fnExpr+  t1Val <- evalExpr env t1Expr+  t2Val <- evalExpr env t2Expr+  case (t1Val, t2Val) of+    (Value (TensorData t1), Value (TensorData t2)) -> do+      tMap2 (applyScalarFunc env fn) t1 t2 >>= (return . Value . TensorData)+    (Value (TensorData _), _) -> throwError $ TypeMismatch "tensor" t1Val+    _ -> throwError $ TypeMismatch "tensor" t2Val+ where+  applyScalarFunc :: Env -> WHNFData -> ScalarData -> ScalarData -> EgisonM ScalarData+  applyScalarFunc env fn s1 s2 = applyFunc env fn (Value (Tuple [(ScalarData s1), (ScalarData s2)])) >>= extractScalar+  extractScalar :: WHNFData -> EgisonM ScalarData+  extractScalar (Value (ScalarData x)) = return x+  extractScalar x = throwError $ TypeMismatch "scalar expression" x+ evalExpr _ SomethingExpr = return $ Value Something evalExpr _ UndefinedExpr = return $ Value Undefined evalExpr _ expr = throwError $ NotImplemented ("evalExpr for " ++ show expr)@@ -392,50 +510,76 @@ evalWHNF (Intermediate (ITuple refs)) = Tuple <$> mapM evalRefDeep refs evalWHNF coll = Collection <$> (fromCollection coll >>= fromMList >>= mapM evalRefDeep . Sq.fromList) -applyFunc :: WHNFData -> WHNFData -> EgisonM WHNFData-applyFunc (Value (Func env [name] body)) arg = do+applyFunc :: Env -> WHNFData -> WHNFData -> EgisonM WHNFData+applyFunc _ (Value (Func _ env [name] body)) arg = do   ref <- newEvalutedObjectRef arg   evalExpr (extendEnv env $ makeBindings [name] [ref]) body-applyFunc (Value (Func env names body)) arg = do+applyFunc _ (Value (Func _ env names body)) arg = do   refs <- fromTuple arg   if length names == length refs     then evalExpr (extendEnv env $ makeBindings names refs) body     else throwError $ ArgumentsNumWithNames names (length names) (length refs)-applyFunc (Value (PrimitiveFunc func)) arg = func arg-applyFunc (Value (IOFunc m)) arg = do+applyFunc _ (Value (CFunc _ env name body)) arg = do+  refs <- fromTuple arg+  seqRef <- liftIO . newIORef $ Sq.fromList (map IElement refs)+  col <- liftIO . newIORef $ WHNF $ Intermediate $ ICollection $ seqRef+  if length refs > 0+    then evalExpr (extendEnv env $ makeBindings [name] [col]) body+    else throwError $ ArgumentsNumWithNames [name] 1 0+applyFunc env (Value (Macro [name] body)) arg = do+  ref <- newEvalutedObjectRef arg+  evalExpr (extendEnv env $ makeBindings [name] [ref]) body+applyFunc env (Value (Macro names body)) arg = do+  refs <- fromTuple arg+  if length names == length refs+    then evalExpr (extendEnv env $ makeBindings names refs) body+    else throwError $ ArgumentsNumWithNames names (length names) (length refs)+applyFunc _ (Value (PrimitiveFunc _ func)) arg = func arg+applyFunc _ (Value (IOFunc m)) arg = do   case arg of      Value World -> m      _ -> throwError $ TypeMismatch "world" arg-applyFunc val _ = throwError $ TypeMismatch "function" val--generateArray :: Env -> String -> EgisonExpr -> EgisonExpr -> EgisonM WHNFData-generateArray env name sizeExpr expr = do-  size <- evalExpr env sizeExpr >>= fromWHNF >>= return . fromInteger-  elems <- mapM genElem (enumFromTo 1 size)-  return $ Intermediate $ IArray $ Array.listArray (1, size) elems-  where-    genElem :: Integer -> EgisonM ObjectRef-    genElem i = do env' <- bindEnv env name $ toInteger i-                   newObjectRef env' expr-    -    bindEnv :: Env -> String -> Integer -> EgisonM Env-    bindEnv env name i = do-      ref <- newEvalutedObjectRef (Value (Number (i,0) (1,0)))-      return $ extendEnv env [(name, ref)]+applyFunc _ (Value fn@(ScalarData (Div (Plus [(Term 1 [(Symbol name [], 1)])]) (Plus [(Term 1 [])])))) arg = do+  args <- tupleToList arg+  mExprs <- mapM p args+  return (Value (ScalarData (Div (Plus [(Term 1 [(Apply fn mExprs, 1)])]) (Plus [(Term 1 [])]))))+ where+  p :: EgisonValue -> EgisonM ScalarData+  p (ScalarData mExpr) = return mExpr+  p val = throwError $ TypeMismatch "math expression" (Value val)+applyFunc _ whnf _ = throwError $ TypeMismatch "function" whnf  refArray :: WHNFData -> [EgisonValue] -> EgisonM WHNFData refArray val [] = return val  refArray (Value (Array array)) (index:indices) = do-  i <- (liftM fromInteger . fromEgison) index-  if (\(a,b) -> if a <= i && i <= b then True else False) $ Array.bounds array-    then refArray (Value (array ! i)) indices-    else return  $ Value Undefined+  if isInteger index+    then do i <- (liftM fromInteger . fromEgison) index+            if (\(a,b) -> if a <= i && i <= b then True else False) $ Array.bounds array+              then refArray (Value (array ! i)) indices+              else return  $ Value Undefined+    else case index of+           (ScalarData (Div (Plus [(Term 1 [(Symbol var [], 1)])]) (Plus [(Term 1 [])]))) -> do+             let (_,size) = Array.bounds array+             elms <- mapM (\arr -> refArray (Value arr) indices) (Array.elems array)+             elmRefs <- mapM newEvalutedObjectRef elms+             return $ Intermediate $ IArray $ Array.listArray (1, size) elmRefs+           _  -> throwError $ TypeMismatch "integer or symbol" (Value index) refArray (Intermediate (IArray array)) (index:indices) = do-  i <- (liftM fromInteger . fromEgison) index-  if (\(a,b) -> if a <= i && i <= b then True else False) $ Array.bounds array-    then let ref = array ! i in-           evalRef ref >>= flip refArray indices-    else return  $ Value Undefined+  if isInteger index+    then do i <- (liftM fromInteger . fromEgison) index+            if (\(a,b) -> if a <= i && i <= b then True else False) $ Array.bounds array+              then let ref = array ! i in+                   evalRef ref >>= flip refArray indices+              else return  $ Value Undefined+    else case index of+           (ScalarData (Div (Plus [(Term 1 [(Symbol var [], 1)])]) (Plus [(Term 1 [])]))) -> do+             let (_,size) = Array.bounds array+             let refs = Array.elems array+             arrs <- mapM evalRef refs+             elms <- mapM (\arr -> refArray arr indices) arrs+             elmRefs <- mapM newEvalutedObjectRef elms+             return $ Intermediate $ IArray $ Array.listArray (1, size) elmRefs+           _  -> throwError $ TypeMismatch "integer or symbol" (Value index) refArray (Value (IntHash hash)) (index:indices) = do   key <- fromEgison index   case HL.lookup key hash of@@ -468,6 +612,14 @@     Nothing -> return $ Value Undefined refArray val _ = throwError $ TypeMismatch "array or hash" val +arrayBounds :: WHNFData -> EgisonM WHNFData+arrayBounds val = arrayBounds' val >>= return . Value++arrayBounds' :: WHNFData -> EgisonM EgisonValue+arrayBounds' (Intermediate (IArray arr)) = return $ Tuple [(toEgison (fst (Array.bounds arr))), (toEgison (snd (Array.bounds arr)))]+arrayBounds' (Value (Array arr))         = return $ Tuple [(toEgison (fst (Array.bounds arr))), (toEgison (snd (Array.bounds arr)))]+arrayBounds' val                         = throwError $ TypeMismatch "array" val+ newThunk :: Env -> EgisonExpr -> Object newThunk env expr = Thunk $ evalExpr env expr @@ -488,13 +640,21 @@   let (names, exprs) = unzip bindings   refs <- replicateM (length bindings) $ newObjectRef nullEnv UndefinedExpr   let env' = extendEnv env $ makeBindings names refs-  zipWithM_ (\ref expr ->+  zipWithM_ (\ref (name,expr) ->                case expr of                  MemoizedLambdaExpr names body -> do                    hashRef <- liftIO $ newIORef HL.empty-                   liftIO . writeIORef ref . WHNF . Value $ MemoizedFunc ref hashRef env' names body+                   liftIO . writeIORef ref . WHNF . Value $ MemoizedFunc (Just name) ref hashRef env' names body+                 LambdaExpr args body -> do+                   whnf <- evalExpr env' expr+                   case whnf of+                     (Value (Func _ env args body)) -> liftIO . writeIORef ref . WHNF $ (Value (Func (Just name) env args body))+                 CambdaExpr arg body -> do+                   whnf <- evalExpr env' expr+                   case whnf of+                     (Value (CFunc _ env arg body)) -> liftIO . writeIORef ref . WHNF $ (Value (CFunc (Just name) env arg body))                  _ -> liftIO . writeIORef ref . Thunk $ evalExpr env' expr)-            refs exprs+            refs bindings   return env'  --@@ -594,7 +754,7 @@     Just pattern -> do       let env'' = extendEnvForNonLinearPatterns env' bindings loops'       indices' <- mapM (evalExpr env'' >=> liftM fromInteger . fromWHNF) indices-      let pattern' = IndexedPat pattern $ map (\i -> NumberExpr (i,0) (1,0)) indices'+      let pattern' = IndexedPat pattern $ map (\i -> IntegerExpr i) indices'       case trees' of         [] -> return $ msingleton $ MState env loops bindings ((MAtom pattern' target matcher):trees)         _ -> return $ msingleton $ MState env loops bindings ((MAtom pattern' target matcher):(MNode penv (MState env' loops' bindings' trees')):trees)@@ -609,7 +769,7 @@   let env' = extendEnvForNonLinearPatterns env bindings loops   case pattern of     NotPat _ -> throwError $ EgisonBug "should not reach here (not pattern)"-    VarPat _ -> throwError $ strMsg "cannot use variable except in pattern function"+    VarPat _ -> throwError $ strMsg $ "cannot use variable except in pattern function:" ++ show pattern      LetPat bindings' pattern' ->       let extractBindings ([name], expr) =@@ -622,21 +782,24 @@     PredPat predicate -> do       func <- evalExpr env' predicate       arg <- evalRef target-      result <- applyFunc func arg >>= fromWHNF+      result <- applyFunc env func arg >>= fromWHNF       if result then return $ msingleton $ (MState env loops bindings trees)                 else return MNil -    ApplyPat func args -> do+    PApplyPat func args -> do       func' <- evalExpr env' func       case func' of         Value (PatternFunc env'' names expr) ->           let penv = zip names args           in return $ msingleton $ MState env loops bindings (MNode penv (MState env'' [] [] [MAtom expr target matcher]) : trees)         _ -> throwError $ TypeMismatch "pattern constructor" func'++    DApplyPat func args -> do+      return $ msingleton $ (MState env loops bindings ((MAtom (InductivePat "apply" [func, (toListPat args)]) target matcher):trees))          LoopPat name (LoopRange start ends endPat) pat pat' -> do-      startNum <- evalExpr env' start >>= fromWHNF-      startNumRef <- newEvalutedObjectRef $ Value $ Number ((startNum - 1),0) (1,0)+      startNum <- evalExpr env' start >>= fromWHNF :: (EgisonM Integer)+      startNumRef <- newEvalutedObjectRef $ Value $ toEgison (startNum - 1)       ends' <- evalExpr env' ends       if isPrimitiveValue ends'         then do @@ -651,8 +814,8 @@       case loops of         [] -> throwError $ strMsg "cannot use cont pattern except in loop pattern"         LoopPatContext (name, startNumRef) endsRef endPat pat pat' : loops' -> do-          startNum <- evalRef startNumRef >>= fromWHNF-          nextNumRef <- newEvalutedObjectRef $ Value $ Number ((startNum + 1),0) (1,0)+          startNum <- evalRef startNumRef >>= fromWHNF :: (EgisonM Integer)+          nextNumRef <- newEvalutedObjectRef $ Value $ toEgison (startNum + 1)           ends <- evalRef endsRef           b <- isEmptyCollection ends           if b@@ -790,6 +953,15 @@       refs <- lift $ mapM (newEvalutedObjectRef . Value) vals       concat <$> zipWithM primitiveDataPatternMatch patterns refs     _ -> matchFail+primitiveDataPatternMatch (PDTuplePat patterns) ref = do+  whnf <- lift $ evalRef ref+  case whnf of+    Intermediate (ITuple refs) ->+      concat <$> zipWithM primitiveDataPatternMatch patterns refs+    Value (Tuple vals) -> do+      refs <- lift $ mapM (newEvalutedObjectRef . Value) vals+      concat <$> zipWithM primitiveDataPatternMatch patterns refs+    _ -> matchFail primitiveDataPatternMatch PDEmptyPat ref = do   whnf <- lift $ evalRef ref   isEmpty <- lift $ isEmptyCollection whnf@@ -884,6 +1056,10 @@ -- -- Util --+toListPat :: [EgisonPattern] -> EgisonPattern+toListPat [] = InductivePat "nil" []+toListPat (pat:pats) = InductivePat "cons" [pat, (toListPat pats)]+ fromTuple :: WHNFData -> EgisonM [ObjectRef] fromTuple (Intermediate (ITuple refs)) = return refs fromTuple (Value (Tuple vals)) = mapM (newEvalutedObjectRef . Value) vals@@ -907,6 +1083,26 @@       return $ MCons head (fromCollection tail') fromCollection whnf = throwError $ TypeMismatch "collection" whnf +tupleToList :: WHNFData -> EgisonM [EgisonValue]+tupleToList whnf = do+  val <- evalWHNF whnf+  return $ tupleToList' val+ where+  tupleToList' (Tuple vals) = vals+  tupleToList' val = [val]++collectionToList :: WHNFData -> EgisonM [EgisonValue]+collectionToList whnf = do+  val <- evalWHNF whnf+  return $ collectionToList' val+ where+  collectionToList' (Collection sq) = toList sq++makeTuple :: [EgisonValue] -> EgisonValue+makeTuple [] = Tuple []+makeTuple [x] = x+makeTuple xs = Tuple xs+ -- -- String --@@ -932,13 +1128,13 @@ extractPrimitiveValue :: WHNFData -> Either EgisonError EgisonValue extractPrimitiveValue (Value val@(Char _)) = return val extractPrimitiveValue (Value val@(Bool _)) = return val-extractPrimitiveValue (Value val@(Number _ _)) = return val+extractPrimitiveValue (Value val@(ScalarData _)) = return val extractPrimitiveValue (Value val@(Float _ _)) = return val extractPrimitiveValue whnf = throwError $ TypeMismatch "primitive value" whnf  isPrimitiveValue :: WHNFData -> Bool isPrimitiveValue (Value (Char _)) = True isPrimitiveValue (Value (Bool _)) = True-isPrimitiveValue (Value (Number _ _)) = True+isPrimitiveValue (Value (ScalarData _)) = True isPrimitiveValue (Value (Float _ _)) = True isPrimitiveValue _ = False
hs-src/Language/Egison/Desugar.hs view
@@ -140,9 +140,14 @@ desugar (IndexedExpr expr indices) =    IndexedExpr <$> desugar expr <*> (mapM desugar indices) -desugar (ArraySizeExpr expr) = do+desugar (PowerExpr expr1 expr2) = do+  expr1' <- desugar expr1+  expr2' <- desugar expr2+  return $ ApplyExpr (VarExpr "**'") (TupleExpr [expr1', expr2'])++desugar (ArrayBoundsExpr expr) = do   expr' <- desugar expr-  return $ ArraySizeExpr expr'+  return $ ArrayBoundsExpr expr'  desugar (InductiveDataExpr name exprs) = do    exprs' <- mapM desugar exprs@@ -181,6 +186,14 @@   expr' <- desugar expr   return $ MemoizeExpr memoizeBindings' expr' +desugar (CambdaExpr name expr) = do+  expr' <- desugar expr+  return $ CambdaExpr name expr'++--desugar (MacroExpr names expr) = do+--  expr' <- desugar expr+--  return $ MacroExpr names expr'+ desugar (PatternFunctionExpr names pattern) = do   pattern' <- desugarPattern pattern   return $ PatternFunctionExpr names pattern'@@ -232,29 +245,38 @@   expr1' <- desugar expr1   return $ SeqExpr expr0' expr1' -desugar (ApplyExpr (VarExpr "+") expr) = do-  expr' <- desugar expr-  case expr' of-    args@(TupleExpr (_:_:[])) -> return $ ApplyExpr (VarExpr "+") args-    (TupleExpr (x:args)) -> return $ ApplyExpr (VarExpr "foldl") (TupleExpr [(VarExpr "+"), x, (CollectionExpr (map ElementExpr args))])+desugar (GenerateArrayExpr fnExpr (fstExpr, lstExpr)) = do+  fnExpr' <- desugar fnExpr+  fstExpr' <- desugar fstExpr+  lstExpr' <- desugar lstExpr+  return $ GenerateArrayExpr fnExpr' (fstExpr', lstExpr') -desugar (ApplyExpr (VarExpr "-") expr) = do-  expr' <- desugar expr-  case expr' of-    args@(TupleExpr (_:_:[])) -> return $ ApplyExpr (VarExpr "-") args-    (TupleExpr (x:args)) -> return $ ApplyExpr (VarExpr "foldl") (TupleExpr [(VarExpr "-"), x, (CollectionExpr (map ElementExpr args))])+desugar (GenerateTensorExpr fnExpr sizeExpr) = do+  fnExpr' <- desugar fnExpr+  sizeExpr' <- desugar sizeExpr+  return $ GenerateTensorExpr fnExpr' sizeExpr' -desugar (ApplyExpr (VarExpr "*") expr) = do-  expr' <- desugar expr-  case expr' of-    args@(TupleExpr (_:_:[])) -> return $ ApplyExpr (VarExpr "*") args-    (TupleExpr (x:args)) -> return $ ApplyExpr (VarExpr "foldl") (TupleExpr [(VarExpr "*"), x, (CollectionExpr (map ElementExpr args))])+desugar (TensorMapExpr fnExpr tExpr) = do+  fnExpr' <- desugar fnExpr+  tExpr' <- desugar tExpr+  return $ TensorMapExpr fnExpr' tExpr' +desugar (TensorMap2Expr fnExpr t1Expr t2Expr) = do+  fnExpr' <- desugar fnExpr+  t1Expr' <- desugar t1Expr+  t2Expr' <- desugar t2Expr+  return $ TensorMap2Expr fnExpr' t1Expr' t2Expr'+ desugar (ApplyExpr expr0 expr1) = do   expr0' <- desugar expr0   expr1' <- desugar expr1   return $ ApplyExpr expr0' expr1' +desugar (CApplyExpr expr0 expr1) = do+  expr0' <- desugar expr0+  expr1' <- desugar expr1+  return $ CApplyExpr expr0' expr1'+ desugar (VarExpr name) = do   asks $ maybe (VarExpr name) id . lookup name @@ -291,7 +313,8 @@    collectName (AndPat patterns) = collectNames patterns    collectName (TuplePat patterns) = collectNames patterns    collectName (InductivePat _ patterns) = collectNames patterns-   collectName (ApplyPat _ patterns) = collectNames patterns+   collectName (PApplyPat _ patterns) = collectNames patterns+   collectName (DApplyPat _ patterns) = collectNames patterns    collectName (LoopPat _ (LoopRange _ _ endNumPat) pattern1 pattern2) = collectName endNumPat `S.union` collectName pattern1 `S.union` collectName pattern2 --   collectName (LoopPat _ (LoopRange _ _ endNumPat) pattern1 pattern2) = collectName pattern1 `S.union` collectName pattern2    collectName (LetPat _ pattern) = collectName pattern@@ -316,7 +339,8 @@ desugarPattern' (TuplePat patterns)  = TuplePat <$> mapM desugarPattern' patterns desugarPattern' (InductivePat name patterns) = InductivePat name <$> mapM desugarPattern' patterns desugarPattern' (IndexedPat pattern exprs) = IndexedPat <$> desugarPattern' pattern <*> mapM desugar exprs-desugarPattern' (ApplyPat expr patterns) = ApplyPat <$> desugar expr <*> mapM desugarPattern' patterns +desugarPattern' (PApplyPat expr patterns) = PApplyPat <$> desugar expr <*> mapM desugarPattern' patterns +desugarPattern' (DApplyPat pattern patterns) = DApplyPat <$> desugarPattern' pattern <*> mapM desugarPattern' patterns  desugarPattern' (LoopPat name range pattern1 pattern2) =  LoopPat name <$> desugarLoopRange range <*> desugarPattern' pattern1 <*> desugarPattern' pattern2 desugarPattern' (LetPat binds pattern) = LetPat <$> desugarBindings binds <*> desugarPattern' pattern desugarPattern' pattern = return pattern
hs-src/Language/Egison/Parser.hs view
@@ -89,7 +89,7 @@ -- |Load a libary file loadLibraryFile :: FilePath -> EgisonM [EgisonTopExpr] loadLibraryFile file =-  if file =~ "^lib/core"+  if file =~ "^lib/"     then liftIO (getDataFileName file) >>= loadFile     else do homeDir <- liftIO $ getHomeDirectory             loadFile $ homeDir ++ "/.egison/" ++ file@@ -151,18 +151,19 @@ exprs = endBy expr whiteSpace  expr :: Parser EgisonExpr-expr = do expr <- expr'-          option expr $ IndexedExpr expr <$> many1 (try $ char '_' >> expr')+expr = P.lexeme lexer (do expr0 <- expr'+                          expr1 <- option expr0 $ PowerExpr expr0 <$> (try $ char '^' >> expr')+                          option expr1 $ IndexedExpr expr1 <$> many1 (try $ char '_' >> expr'))  expr' :: Parser EgisonExpr expr' = (try partialExpr              <|> try constantExpr              <|> try partialVarExpr-             <|> contExpr              <|> recVarExpr              <|> try varExpr              <|> inductiveDataExpr              <|> try arrayExpr+             <|> try tensorExpr              <|> try tupleExpr              <|> try hashExpr              <|> collectionExpr@@ -170,6 +171,8 @@                          <|> lambdaExpr                          <|> memoizedLambdaExpr                          <|> memoizeExpr+                         <|> cambdaExpr+                         <|> macroExpr                          <|> patternFunctionExpr                          <|> letRecExpr                          <|> letExpr@@ -189,10 +192,16 @@                          <|> matcherDFSExpr                          <|> seqExpr                          <|> applyExpr+                         <|> cApplyExpr                          <|> algebraicDataMatcherExpr                          <|> generateArrayExpr-                         <|> arraySizeExpr-                         <|> arrayRefExpr)+                         <|> arrayBoundsExpr+                         <|> arrayRefExpr+                         <|> generateTensorExpr+                         <|> initTensorExpr+                         <|> tensorMapExpr+                         <|> tensorMap2Expr+                         )              <?> "expression")  varExpr :: Parser EgisonExpr@@ -215,13 +224,19 @@ arrayExpr = between lp rp $ ArrayExpr <$> sepEndBy expr whiteSpace   where     lp = P.lexeme lexer (string "[|")-    rp = P.lexeme lexer (string "|]")+    rp = string "|]" +tensorExpr :: Parser EgisonExpr+tensorExpr = between lp rp $ TensorExpr <$> expr <*> expr+  where+    lp = P.lexeme lexer (string "(|")+    rp = string "|)"+ hashExpr :: Parser EgisonExpr hashExpr = between lp rp $ HashExpr <$> sepEndBy pairExpr whiteSpace   where     lp = P.lexeme lexer (string "{|")-    rp = P.lexeme lexer (string "|}")+    rp = string "|}"     pairExpr :: Parser (EgisonExpr, EgisonExpr)     pairExpr = brackets $ (,) <$> expr <*> expr @@ -268,7 +283,7 @@ ppMatchClauses = braces $ sepEndBy ppMatchClause whiteSpace  ppMatchClause :: Parser (PrimitivePatPattern, EgisonExpr, [(PrimitiveDataPattern, EgisonExpr)])-ppMatchClause = brackets $ (,,) <$> pppattern <*> expr <*> pdMatchClauses+ppMatchClause = brackets $ (,,) <$> ppPattern <*> expr <*> pdMatchClauses  pdMatchClauses :: Parser [(PrimitiveDataPattern, EgisonExpr)] pdMatchClauses = braces $ sepEndBy pdMatchClause whiteSpace@@ -276,32 +291,36 @@ pdMatchClause :: Parser (PrimitiveDataPattern, EgisonExpr) pdMatchClause = brackets $ (,) <$> pdPattern <*> expr -pppattern :: Parser PrimitivePatPattern-pppattern = ppWildCard-                 <|> pppatVar-                 <|> ppValuePat-                 <|> ppInductivePat-                 <?> "primitive-pattren-pattern"+ppPattern :: Parser PrimitivePatPattern+ppPattern = P.lexeme lexer (ppWildCard+                        <|> ppPatVar+                        <|> ppValuePat+                        <|> ppInductivePat+                        <?> "primitive-pattren-pattern")                         ppWildCard :: Parser PrimitivePatPattern ppWildCard = reservedOp "_" *> pure PPWildCard -pppatVar :: Parser PrimitivePatPattern-pppatVar = reservedOp "$" *> pure PPPatVar+ppPatVar :: Parser PrimitivePatPattern+ppPatVar = reservedOp "$" *> pure PPPatVar  ppValuePat :: Parser PrimitivePatPattern ppValuePat = string ",$" >> PPValuePat <$> ident  ppInductivePat :: Parser PrimitivePatPattern-ppInductivePat = angles (PPInductivePat <$> lowerName <*> sepEndBy pppattern whiteSpace)+ppInductivePat = angles (PPInductivePat <$> lowerName <*> sepEndBy ppPattern whiteSpace)  pdPattern :: Parser PrimitiveDataPattern-pdPattern = reservedOp "_" *> pure PDWildCard+pdPattern = P.lexeme lexer $ pdPattern'++pdPattern' :: Parser PrimitiveDataPattern+pdPattern' = reservedOp "_" *> pure PDWildCard                     <|> (char '$' >> PDPatVar <$> ident)                     <|> braces ((PDConsPat <$> pdPattern <*> (char '@' *> pdPattern))                             <|> (PDSnocPat <$> (char '@' *> pdPattern) <*> pdPattern)                              <|> pure PDEmptyPat)                     <|> angles (PDInductivePat <$> upperName <*> sepEndBy pdPattern whiteSpace)+                    <|> brackets (PDTuplePat <$> sepEndBy pdPattern whiteSpace)                     <|> PDConstantPat <$> constantExpr                     <?> "primitive-data-pattern" @@ -323,6 +342,12 @@ memoizeBinding :: Parser (EgisonExpr, EgisonExpr, EgisonExpr) memoizeBinding = brackets $ (,,) <$> expr <*> expr <*> expr +cambdaExpr :: Parser EgisonExpr+cambdaExpr = keywordCambda >> CambdaExpr <$> varName <*> expr++macroExpr :: Parser EgisonExpr+macroExpr = keywordMacro >> MacroExpr <$> varNames <*> expr+ patternFunctionExpr :: Parser EgisonExpr patternFunctionExpr = keywordPatternFunction >> PatternFunctionExpr <$> varNames <*> pattern @@ -365,12 +390,12 @@ seqExpr :: Parser EgisonExpr seqExpr = keywordSeq >> SeqExpr <$> expr <*> expr -contExpr :: Parser EgisonExpr-contExpr = reservedOp "..." >> pure ContExpr- recVarExpr :: Parser EgisonExpr recVarExpr = reservedOp "#" >> pure RecVarExpr +cApplyExpr :: Parser EgisonExpr+cApplyExpr = (keywordCApply >> CApplyExpr <$> expr <*> expr) + applyExpr :: Parser EgisonExpr applyExpr = (keywordApply >> ApplyExpr <$> expr <*> expr)               <|> applyExpr'@@ -418,22 +443,40 @@     inductivePat' = angles $ (,) <$> lowerName <*> sepEndBy expr whiteSpace  generateArrayExpr :: Parser EgisonExpr-generateArrayExpr = keywordGenerateArray >> GenerateArrayExpr <$> varNames <*> expr <*> expr+generateArrayExpr = keywordGenerateArray >> GenerateArrayExpr <$> expr <*> arrayRange -arraySizeExpr :: Parser EgisonExpr-arraySizeExpr = keywordArraySize >> ArraySizeExpr <$> expr+arrayRange :: Parser (EgisonExpr, EgisonExpr)+arrayRange = brackets (do s <- expr+                          e <- expr+                          return (s, e)) +arrayBoundsExpr :: Parser EgisonExpr+arrayBoundsExpr = keywordArrayBounds >> ArrayBoundsExpr <$> expr+ arrayRefExpr :: Parser EgisonExpr arrayRefExpr = keywordArrayRef >> ArrayRefExpr <$> expr <*> expr +generateTensorExpr :: Parser EgisonExpr+generateTensorExpr = keywordGenerateTensor >> GenerateTensorExpr <$> expr <*> expr++initTensorExpr :: Parser EgisonExpr+initTensorExpr = keywordInitTensor >> InitTensorExpr <$> expr <*> expr <*> expr++tensorMapExpr :: Parser EgisonExpr+tensorMapExpr = keywordTensorMap >> TensorMapExpr <$> expr <*> expr++tensorMap2Expr :: Parser EgisonExpr+tensorMap2Expr = keywordTensorMap2 >> TensorMap2Expr <$> expr <*> expr <*> expr+ -- Patterns  pattern :: Parser EgisonPattern-pattern = do pattern <- pattern'-             option pattern $ IndexedPat pattern <$> many1 (try $ char '_' >> expr')+pattern = P.lexeme lexer (do pattern <- pattern'+                             option pattern $ IndexedPat pattern <$> many1 (try $ char '_' >> expr'))  pattern' :: Parser EgisonPattern pattern' = wildCard+            <|> contPat             <|> patVar             <|> varPat             <|> valuePat@@ -442,25 +485,31 @@             <|> notPat             <|> tuplePat             <|> inductivePat-            <|> contPat             <|> parens (andPat                     <|> orderedOrPat                     <|> orPat-                    <|> applyPat                     <|> loopPat-                    <|> letPat)+                    <|> letPat+                    <|> try dApplyPat+                    <|> try pApplyPat+                    ) +pattern'' :: Parser EgisonPattern+pattern'' = wildCard+            <|> patVar+            <|> valuePat+ wildCard :: Parser EgisonPattern wildCard = reservedOp "_" >> pure WildCard  patVar :: Parser EgisonPattern-patVar = P.lexeme lexer $ PatVar <$> varName+patVar = PatVar <$> varName  varPat :: Parser EgisonPattern varPat = VarPat <$> ident  valuePat :: Parser EgisonPattern-valuePat = reservedOp "," >> ValuePat <$> expr+valuePat = char ',' >> ValuePat <$> expr  regexPat :: Parser EgisonPattern regexPat = reservedOp "~" >> RegexPat <$> expr@@ -472,7 +521,7 @@ letPat = keywordLet >> LetPat <$> bindings <*> pattern  notPat :: Parser EgisonPattern-notPat = reservedOp "^" >> NotPat <$> pattern+notPat = reservedOp "!" >> NotPat <$> pattern  tuplePat :: Parser EgisonPattern tuplePat = brackets $ TuplePat <$> sepEndBy pattern whiteSpace@@ -481,7 +530,7 @@ inductivePat = angles $ InductivePat <$> lowerName <*> sepEndBy pattern whiteSpace  contPat :: Parser EgisonPattern-contPat = reservedOp "..." >> pure ContPat+contPat = keywordCont >> pure ContPat  andPat :: Parser EgisonPattern andPat = reservedOp "&" >> AndPat <$> sepEndBy pattern whiteSpace@@ -492,9 +541,12 @@ orderedOrPat :: Parser EgisonPattern orderedOrPat = reservedOp "|*" >> OrderedOrPat <$> sepEndBy pattern whiteSpace -applyPat :: Parser EgisonPattern-applyPat = ApplyPat <$> expr <*> sepEndBy pattern whiteSpace +pApplyPat :: Parser EgisonPattern+pApplyPat = PApplyPat <$> expr <*> sepEndBy pattern whiteSpace  +dApplyPat :: Parser EgisonPattern+dApplyPat = DApplyPat <$> pattern'' <*> sepEndBy pattern whiteSpace + loopPat :: Parser EgisonPattern loopPat = keywordLoop >> LoopPat <$> varName <*> loopRange <*> pattern <*> option (NotPat WildCard) pattern @@ -505,7 +557,7 @@                               return (LoopRange s e ep))                  <|> (do s <- expr                          ep <- option WildCard pattern-                         return (LoopRange s (ApplyExpr (VarExpr "from") (ApplyExpr (VarExpr "-") (TupleExpr [s, (NumberExpr (1, 0) (1, 0))]))) ep)))+                         return (LoopRange s (ApplyExpr (VarExpr "from") (ApplyExpr (VarExpr "-") (TupleExpr [s, (IntegerExpr 1)]))) ep)))  -- Constants @@ -514,7 +566,7 @@                  <|> stringExpr                  <|> boolExpr                  <|> try floatExpr-                 <|> try numberExpr+                 <|> try integerExpr                  <|> (keywordSomething *> pure SomethingExpr)                  <|> (keywordUndefined *> pure UndefinedExpr)                  <?> "constant"@@ -530,39 +582,21 @@  floatExpr :: Parser EgisonExpr floatExpr = do-  (x,y) <- P.lexeme lexer $ try (do x <- floatLiteral'-                                    y <- sign' <*> positiveFloatLiteral-                                    char 'i'-                                    return (x,y))-                            <|> try (do y <- floatLiteral'-                                        char 'i'-                                        return (0,y))-                            <|> try (do x <- floatLiteral'-                                        return (x,0))+  (x,y) <- try (do x <- floatLiteral'+                   y <- sign' <*> positiveFloatLiteral+                   char 'i'+                   return (x,y))+            <|> try (do y <- floatLiteral'+                        char 'i'+                        return (0,y))+            <|> try (do x <- floatLiteral'+                        return (x,0))   return $ FloatExpr x y -numberExpr :: Parser EgisonExpr-numberExpr = do-  (m,n) <- P.lexeme lexer $ try (do m <- gaussianIntegerLiteral-                                    char '/'-                                    n <- gaussianIntegerLiteral-                                    return (m,n))-                            <|> try (do m <- gaussianIntegerLiteral-                                        return (m,(1,0)))-  return $ NumberExpr m n--gaussianIntegerLiteral :: Parser (Integer, Integer)-gaussianIntegerLiteral = do-  (x,y) <- P.lexeme lexer $ try (do x <- integerLiteral'-                                    y <- sign' <*> positiveIntegerLiteral-                                    char 'i'-                                    return (x,y))-                            <|> try (do y <- integerLiteral'-                                        char 'i'-                                        return (0,y))-                            <|> try (do x <- integerLiteral'-                                        return (x,0))-  return (x,y)+integerExpr :: Parser EgisonExpr+integerExpr = do+  n <- integerLiteral'+  return $ IntegerExpr n  integerLiteral' :: Parser Integer integerLiteral' = sign <*> positiveIntegerLiteral@@ -599,10 +633,10 @@                 , P.reservedOpNames    = reservedOperators                 , P.nestedComments     = True                 , P.caseSensitive      = True }- where-  symbol1 = oneOf "+-*/="-  symbol2 = symbol1 <|> oneOf "'!?." +symbol1 = oneOf "+-*/=."+symbol2 = symbol1 <|> oneOf "'!?"+ lexer :: P.GenTokenParser String () Identity lexer = P.makeTokenParser egisonDef @@ -616,9 +650,12 @@   , "if"   , "seq"   , "apply"+  , "capply"   , "lambda"   , "memoized-lambda"   , "memoize"+  , "cambda"+  , "macro"   , "pattern-function"   , "letrec"   , "let"@@ -635,8 +672,12 @@   , "io"   , "algebraic-data-matcher"   , "generate-array"-  , "array-size"+  , "array-bounds"   , "array-ref"+  , "generate-tensor"+  , "init-tensor"+  , "tensor-map"+  , "tensor-map2"   , "something"   , "undefined"]   @@ -644,12 +685,13 @@ reservedOperators =    [ "$"   , "_"+  , "^"   , "&"   , "|"   , "|*"-  , "^"+  , "!"   , ","-  , "."+  , "~"   , "@"   , "..."] @@ -669,14 +711,18 @@ keywordElse                 = reserved "else" keywordSeq                  = reserved "seq" keywordApply                = reserved "apply"+keywordCApply               = reserved "capply" keywordLambda               = reserved "lambda" keywordMemoizedLambda       = reserved "memoized-lambda" keywordMemoize              = reserved "memoize"+keywordCambda               = reserved "cambda"+keywordMacro                = reserved "macro" keywordPatternFunction      = reserved "pattern-function" keywordLetRec               = reserved "letrec" keywordLet                  = reserved "let" keywordLetStar              = reserved "let*" keywordLoop                 = reserved "loop"+keywordCont                 = reserved "..." keywordMatchAll             = reserved "match-all" keywordMatchAllLambda       = reserved "match-all-lambda" keywordMatch                = reserved "match"@@ -694,8 +740,12 @@ keywordUndefined            = reserved "undefined" keywordAlgebraicDataMatcher = reserved "algebraic-data-matcher" keywordGenerateArray        = reserved "generate-array"-keywordArraySize            = reserved "array-size"+keywordArrayBounds          = reserved "array-bounds" keywordArrayRef             = reserved "array-ref"+keywordGenerateTensor       = reserved "generate-tensor"+keywordInitTensor           = reserved "init-tensor"+keywordTensorMap            = reserved "tensor-map"+keywordTensorMap2           = reserved "tensor-map2"  sign :: Num a => Parser (a -> a) sign = (char '-' >> return negate)@@ -722,7 +772,7 @@ charLiteral = P.charLiteral lexer  boolLiteral :: Parser Bool-boolLiteral = P.lexeme lexer $ char '#' >> (char 't' *> pure True <|> char 'f' *> pure False)+boolLiteral = char '#' >> (char 't' *> pure True <|> char 'f' *> pure False)  whiteSpace :: Parser () whiteSpace = P.whiteSpace lexer@@ -750,19 +800,21 @@  ident :: Parser String ident = P.identifier lexer-    <|> try ((:) <$> char '+' <*> ident)-    <|> try ((:) <$> char '-' <*> ident)-    <|> (P.lexeme lexer $ string "+")-    <|> (P.lexeme lexer $ string "-")  upperName :: Parser String-upperName = P.lexeme lexer $ (:) <$> upper <*> option "" ident+upperName = P.lexeme lexer $ upperName'++upperName' :: Parser String+upperName' = (:) <$> upper <*> option "" ident  where   upper :: Parser Char    upper = satisfy isUpper  lowerName :: Parser String-lowerName = P.lexeme lexer $ (:) <$> lower <*> option "" ident+lowerName = P.lexeme lexer $ lowerName'++lowerName' :: Parser String+lowerName' = (:) <$> lower <*> option "" ident  where   lower :: Parser Char    lower = satisfy isLower
hs-src/Language/Egison/Primitives.hs view
@@ -13,6 +13,7 @@ import Control.Arrow import Control.Monad.Error import Control.Monad.Trans.Maybe+import Control.Applicative ((<$>), (<*>), (*>), (<*), pure)  import Data.IORef import Data.Ratio@@ -40,7 +41,7 @@  primitiveEnv :: IO Env primitiveEnv = do-  let ops = map (second PrimitiveFunc) (primitives ++ ioPrimitives)+  let ops = map (\(name, fn) -> (name, PrimitiveFunc name fn)) (primitives ++ ioPrimitives)   bindings <- forM (constants ++ ops) $ \(name, op) -> do     ref <- newIORef . WHNF $ Value op     return (name, ref)@@ -48,7 +49,7 @@  primitiveEnvNoIO :: IO Env primitiveEnvNoIO = do-  let ops = map (second PrimitiveFunc) primitives+  let ops = map (\(name, fn) -> (name, PrimitiveFunc name fn)) primitives   bindings <- forM (constants ++ ops) $ \(name, op) -> do     ref <- newIORef . WHNF $ Value op     return (name, ref)@@ -84,40 +85,40 @@     [val, val', val''] -> f val val' val'' >>= return . Value     _ -> throwError $ ArgumentsNumPrimitive 3 $ length args' -tupleToList :: WHNFData -> EgisonM [EgisonValue]-tupleToList whnf = do-  val <- evalWHNF whnf-  return $ tupleToList' val- where-  tupleToList' (Tuple vals) = vals-  tupleToList' val = [val]- -- -- Constants --  constants :: [(String, EgisonValue)]-constants = [ ("pi", Float 3.141592653589793 0) ]+constants = [+              ("f.pi", Float 3.141592653589793 0)+             ,("f.e" , Float 2.718281828459045 0)+              ]  -- -- Primitives --  primitives :: [(String, PrimitiveFunc)]-primitives = [ ("+", plus)-             , ("-", minus)-             , ("*", multiply)-             , ("/", divide)+primitives = [ ("b.+", plus)+             , ("b.-", minus)+             , ("b.*", multiply)+             , ("b./", divide)+             , ("b.+'", plus)+             , ("b.-'", minus)+             , ("b.*'", multiply)+             , ("b./'", divide)              , ("numerator", numerator')              , ("denominator", denominator')-             , ("real-part", realPart)-             , ("imaginary-part", imaginaryPart)-               +             , ("from-math-expr", fromScalarData)+             , ("to-math-expr", toScalarData)+             , ("to-math-expr'", toScalarData)+              , ("modulo",    integerBinaryOp mod)              , ("quotient",   integerBinaryOp quot)              , ("remainder", integerBinaryOp rem)-             , ("neg", rationalUnaryOp negate)              , ("abs", rationalUnaryOp abs)+             , ("neg", rationalUnaryOp negate)                              , ("eq?",  eq)              , ("lt?",  lt)@@ -129,23 +130,32 @@              , ("floor",    floatToIntegerOp floor)              , ("ceiling",  floatToIntegerOp ceiling)              , ("truncate", truncate')-               -             , ("sqrt", floatUnaryOp sqrt)-             , ("exp", floatUnaryOp exp)-             , ("log", floatUnaryOp log)-             , ("sin", floatUnaryOp sin)-             , ("cos", floatUnaryOp cos)-             , ("tan", floatUnaryOp tan)-             , ("asin", floatUnaryOp asin)-             , ("acos", floatUnaryOp acos)-             , ("atan", floatUnaryOp atan)-             , ("sinh", floatUnaryOp sinh)-             , ("cosh", floatUnaryOp cosh)-             , ("tanh", floatUnaryOp tanh)-             , ("asinh", floatUnaryOp asinh)-             , ("acosh", floatUnaryOp acosh)-             , ("atanh", floatUnaryOp atanh)+             , ("real-part", realPart)+             , ("imaginary-part", imaginaryPart)                +             , ("b.sqrt", floatUnaryOp sqrt)+             , ("b.sqrt'", floatUnaryOp sqrt)+             , ("b.exp", floatUnaryOp exp)+             , ("b.log", floatUnaryOp log)+             , ("b.sin", floatUnaryOp sin)+             , ("b.cos", floatUnaryOp cos)+             , ("b.tan", floatUnaryOp tan)+             , ("b.asin", floatUnaryOp asin)+             , ("b.acos", floatUnaryOp acos)+             , ("b.atan", floatUnaryOp atan)+             , ("b.sinh", floatUnaryOp sinh)+             , ("b.cosh", floatUnaryOp cosh)+             , ("b.tanh", floatUnaryOp tanh)+             , ("b.asinh", floatUnaryOp asinh)+             , ("b.acosh", floatUnaryOp acosh)+             , ("b.atanh", floatUnaryOp atanh)++             , ("b..", tensorProd)+             , ("b..'", tensorProd)+             , ("tensor-index", tensorIndex)+             , ("tensor-size", tensorSize)+             , ("tensor-to-list", tensorToList)+              , ("itof", integerToFloat)              , ("rtof", rationalToFloat)              , ("ctoi", charToInteger)@@ -171,16 +181,18 @@              , ("uncons", uncons')              , ("unsnoc", unsnoc') -             , ("bool?", isBool)-             , ("integer?", isInteger)-             , ("rational?", isRational)-             , ("number?", isNumber)-             , ("float?", isFloat)-             , ("char?", isChar)-             , ("string?", isString)-             , ("collection?", isCollection)-             , ("array?", isArray)-             , ("hash?", isHash)+             , ("bool?", isBool')+             , ("integer?", isInteger')+             , ("rational?", isRational')+             , ("number?", isNumber')+             , ("float?", isFloat')+             , ("char?", isChar')+             , ("string?", isString')+             , ("collection?", isCollection')+             , ("array?", isArray')+             , ("hash?", isHash')+             , ("tensor?", isTensor')+             , ("tensor-with-index?", isTensorWithIndex')               , ("assert", assert)              , ("assert-equal", assertEqual)@@ -190,14 +202,14 @@ rationalUnaryOp op = oneArg $ \val -> do   r <- fromEgison val   let r' =  op r-  return $ Number ((numerator r'), 0) ((denominator r'), 0)+  return $ toEgison r'    rationalBinaryOp :: (Rational -> Rational -> Rational) -> PrimitiveFunc rationalBinaryOp op = twoArgs $ \val val' -> do   r <- fromEgison val :: EgisonM Rational   r' <- fromEgison val' :: EgisonM Rational   let r'' = (op r r'')-  return $ Number ((numerator r''), 0) ((denominator r''), 0)+  return $ toEgison r''  rationalBinaryPred :: (Rational -> Rational -> Bool) -> PrimitiveFunc rationalBinaryPred pred = twoArgs $ \val val' -> do@@ -209,7 +221,7 @@ integerBinaryOp op = twoArgs $ \val val' -> do   i <- fromEgison val   i' <- fromEgison val'-  return $ Number ((op i i'), 0) (1, 0)+  return $ toEgison (op i i')  integerBinaryPred :: (Integer -> Integer -> Bool) -> PrimitiveFunc integerBinaryPred pred = twoArgs $ \val val' -> do@@ -221,15 +233,13 @@ floatUnaryOp op = oneArg $ \val -> do   case val of     (Float f 0) -> return $ Float (op f) 0-    n@(Number _ _) -> do-      r <- fromEgison n-      return $ Float (op (fromRational r)) 0+    _ -> throwError $ TypeMismatch "float" (Value val)  floatBinaryOp :: (Double -> Double -> Double) -> PrimitiveFunc floatBinaryOp op = twoArgs $ \val val' -> do-  f <- fromEgison val-  f' <- fromEgison val'-  return $ Float (op f f') 0+  case (val, val') of+    ((Float f 0), (Float f' 0)) -> return $ Float (op f f') 0+    _ -> throwError $ TypeMismatch "float" (Value val)  floatBinaryPred :: (Double -> Double -> Bool) -> PrimitiveFunc floatBinaryPred pred = twoArgs $ \val val' -> do@@ -240,71 +250,66 @@ -- -- Arith ---plus :: PrimitiveFunc-plus = twoArgs $ \val val' -> numberBinaryOp' val val'++numberUnaryOp :: (ScalarData -> ScalarData) -> (EgisonValue -> EgisonValue) -> PrimitiveFunc+numberUnaryOp mOp fOp arg = do+  arg' <- tupleToList arg+  case arg' of +    [val] -> numberUnaryOp' val >>= return . Value+    _ -> throwError $ ArgumentsNumPrimitive 1 $ length arg'  where-  numberBinaryOp' (Number x y) (Number x' y') = return $ reduceFraction $ Number (addInteger' (mulInteger' x y') (mulInteger' x' y)) (mulInteger' y y')-  numberBinaryOp' (Float x y)  (Float x' y')  = return $ Float (x + x') (y + y')-  numberBinaryOp' val          (Float x' y')  = numberBinaryOp' (numberToFloat' val) (Float x' y')-  numberBinaryOp' (Float x y)  val'           = numberBinaryOp' (Float x y) (numberToFloat' val')-  numberBinaryOp' (Number _ _) val'           = throwError $ TypeMismatch "number" (Value val')-  numberBinaryOp' val          _              = throwError $ TypeMismatch "number" (Value val)+  numberUnaryOp' f@(Float _ _)  = return $ fOp f+  numberUnaryOp' (ScalarData m) = (return . ScalarData . mathNormalize') (mOp m)+  numberUnaryOp' val            = throwError $ TypeMismatch "number" (Value val) -minus :: PrimitiveFunc-minus = twoArgs $ \val val' -> numberBinaryOp' val val'+numberBinaryOp :: (ScalarData -> ScalarData -> ScalarData) -> (EgisonValue -> EgisonValue -> EgisonValue) -> PrimitiveFunc+numberBinaryOp mOp fOp args = do+  args' <- tupleToList args+  case args' of +    [val, val'] -> numberBinaryOp' val val' >>= return . Value+    _ -> throwError $ ArgumentsNumPrimitive 2 $ length args'  where-  numberBinaryOp' (Number x y) (Number x' y') = return $ reduceFraction $ Number (subInteger' (mulInteger' x y') (mulInteger' x' y)) (mulInteger' y y')-  numberBinaryOp' (Float x y)  (Float x' y')  = return $ Float (x - x') (y - y')-  numberBinaryOp' val          (Float x' y')  = numberBinaryOp' (numberToFloat' val) (Float x' y')-  numberBinaryOp' (Float x y)  val'           = numberBinaryOp' (Float x y) (numberToFloat' val')-  numberBinaryOp' (Number _ _) val'           = throwError $ TypeMismatch "number" (Value val')-  numberBinaryOp' val          _              = throwError $ TypeMismatch "number" (Value val)+  numberBinaryOp' f@(Float _ _)   f'@(Float _ _)  = return $ fOp f f'+  numberBinaryOp' val             (Float x' y')   = numberBinaryOp' (numberToFloat' val) (Float x' y')+  numberBinaryOp' (Float x y)     val'            = numberBinaryOp' (Float x y) (numberToFloat' val')+  numberBinaryOp' (ScalarData m1) (ScalarData m2) = (return . ScalarData . mathNormalize') (mOp m1 m2)+  numberBinaryOp' (ScalarData _)  val'            = throwError $ TypeMismatch "number" (Value val')+  numberBinaryOp' val             _               = throwError $ TypeMismatch "number" (Value val) +plus :: PrimitiveFunc+plus = numberBinaryOp mathPlus (\(Float x y) (Float x' y') -> Float (x + x')  (y + y'))++minus :: PrimitiveFunc+minus = numberBinaryOp (\m1 m2 -> mathPlus m1 (mathNegate m2)) (\(Float x y) (Float x' y') -> Float (x - x')  (y - y'))+ multiply :: PrimitiveFunc-multiply = twoArgs $ \val val' -> numberBinaryOp' val val'- where-  numberBinaryOp' (Number x y) (Number x' y') = return $ reduceFraction $ Number (mulInteger' x x') (mulInteger' y y')-  numberBinaryOp' (Float x y)  (Float x' y')  = return $ Float (x * x' - y * y')  (x * y' + x' * y) -  numberBinaryOp' val          (Float x' y')  = numberBinaryOp' (numberToFloat' val) (Float x' y')-  numberBinaryOp' (Float x y)  val'           = numberBinaryOp' (Float x y) (numberToFloat' val')-  numberBinaryOp' (Number _ _) val'           = throwError $ TypeMismatch "number" (Value val')-  numberBinaryOp' val          _              = throwError $ TypeMismatch "number" (Value val)+multiply = numberBinaryOp mathMult (\(Float x y) (Float x' y') -> Float (x * x' - y * y')  (x * y' + x' * y))  divide :: PrimitiveFunc-divide = twoArgs $ \val val' -> numberBinaryOp' val val'- where-  numberBinaryOp' (Number x y) (Number x' y') = return $ reduceFraction $ Number (mulInteger' x y') (mulInteger' y x')-  numberBinaryOp' (Float f 0)    (Float f' 0) = return $ Float (f / f') 0-  numberBinaryOp' val          (Float x' y')  = numberBinaryOp' (numberToFloat' val) (Float x' y')-  numberBinaryOp' (Float x y)  val'           = numberBinaryOp' (Float x y) (numberToFloat' val')-  numberBinaryOp' (Number _ _) val'           = throwError $ TypeMismatch "number" (Value val')-  numberBinaryOp' val          _              = throwError $ TypeMismatch "number" (Value val)+divide = numberBinaryOp (\m1 (Div p1 p2) -> mathMult m1 (Div p2 p1)) (\(Float x y) (Float x' y') -> Float ((x * x' + y * y') / (x' * x' + y' * y')) ((y * x' - x * y') / (x' * x' + y' * y')))  numerator' :: PrimitiveFunc numerator' =  oneArg $ numerator''  where-  numerator'' (Number (x,y) _) = return (Number (x,y) (1,0))+  numerator'' (ScalarData m) = return $ ScalarData (mathNumerator m)   numerator'' val = throwError $ TypeMismatch "rational" (Value val)  denominator' :: PrimitiveFunc denominator' =  oneArg $ denominator''  where-  denominator'' (Number _ (x,y)) = return (Number (x,y) (1,0))+  denominator'' (ScalarData m) = return $ ScalarData (mathDenominator m)   denominator'' val = throwError $ TypeMismatch "rational" (Value val) -realPart :: PrimitiveFunc-realPart =  oneArg $ realPart'+fromScalarData :: PrimitiveFunc+fromScalarData = oneArg $ fromScalarData'  where-  realPart' (Number (x,_) (x',0)) = return $ Number (x,0) (x',0)-  realPart' (Number _ _) =  throwError $ Default "real-part: denominator is not integer"-  realPart' val = throwError $ TypeMismatch "number" (Value val)+  fromScalarData' (ScalarData m) = return $ mathExprToEgison m+  fromScalarData' val = throwError $ TypeMismatch "number" (Value val) -imaginaryPart :: PrimitiveFunc-imaginaryPart =  oneArg $ imaginaryPart'+toScalarData :: PrimitiveFunc+toScalarData = oneArg $ toScalarData'  where-  imaginaryPart' (Number (_,y) (x',0)) = return $ Number (y,0) (x',0)-  imaginaryPart' (Number _ _) =  throwError $ Default "imaginary-part: denominator is not integer"-  imaginaryPart' val = throwError $ TypeMismatch "number" (Value val)+  toScalarData' val = egisonToScalarData val >>= return . ScalarData . mathNormalize'  -- -- Pred@@ -316,63 +321,111 @@ lt :: PrimitiveFunc lt = twoArgs $ \val val' -> numberBinaryPred' val val'  where-  numberBinaryPred' m@(Number _ _) n@(Number _ _) = do+  numberBinaryPred' m@(ScalarData _) n@(ScalarData _) = do     r <- fromEgison m :: EgisonM Rational     r' <- fromEgison n :: EgisonM Rational     return $ Bool $ (<) r r'   numberBinaryPred' (Float f 0)  (Float f' 0)  = return $ Bool $ (<) f f'-  numberBinaryPred' (Number _ _) val           = throwError $ TypeMismatch "number" (Value val)+  numberBinaryPred' (ScalarData _) val           = throwError $ TypeMismatch "number" (Value val)   numberBinaryPred' (Float _ _)  val           = throwError $ TypeMismatch "float" (Value val)   numberBinaryPred' val          _             = throwError $ TypeMismatch "number" (Value val)    lte :: PrimitiveFunc lte = twoArgs $ \val val' -> numberBinaryPred' val val'  where-  numberBinaryPred' m@(Number _ _) n@(Number _ _) = do+  numberBinaryPred' m@(ScalarData _) n@(ScalarData _) = do     r <- fromEgison m :: EgisonM Rational     r' <- fromEgison n :: EgisonM Rational     return $ Bool $ (<=) r r'   numberBinaryPred' (Float f 0)  (Float f' 0)  = return $ Bool $ (<=) f f'-  numberBinaryPred' (Number _ _) val           = throwError $ TypeMismatch "number" (Value val)+  numberBinaryPred' (ScalarData _) val           = throwError $ TypeMismatch "number" (Value val)   numberBinaryPred' (Float _ _)  val           = throwError $ TypeMismatch "float" (Value val)   numberBinaryPred' val          _             = throwError $ TypeMismatch "number" (Value val)    gt :: PrimitiveFunc gt = twoArgs $ \val val' -> numberBinaryPred' val val'  where-  numberBinaryPred' m@(Number _ _) n@(Number _ _) = do+  numberBinaryPred' m@(ScalarData _) n@(ScalarData _) = do     r <- fromEgison m :: EgisonM Rational     r' <- fromEgison n :: EgisonM Rational     return $ Bool $ (>) r r'   numberBinaryPred' (Float f 0)  (Float f' 0)  = return $ Bool $ (>) f f'-  numberBinaryPred' (Number _ _) val           = throwError $ TypeMismatch "number" (Value val)+  numberBinaryPred' (ScalarData _) val           = throwError $ TypeMismatch "number" (Value val)   numberBinaryPred' (Float _ _)  val           = throwError $ TypeMismatch "float" (Value val)   numberBinaryPred' val          _             = throwError $ TypeMismatch "number" (Value val)    gte :: PrimitiveFunc gte = twoArgs $ \val val' -> numberBinaryPred' val val'  where-  numberBinaryPred' m@(Number _ _) n@(Number _ _) = do+  numberBinaryPred' m@(ScalarData _) n@(ScalarData _) = do     r <- fromEgison m :: EgisonM Rational     r' <- fromEgison n :: EgisonM Rational     return $ Bool $ (>=) r r'-  numberBinaryPred' (Float f 0)  (Float f' 0)  = return $ Bool $ (>=) f f'-  numberBinaryPred' (Number _ _) val           = throwError $ TypeMismatch "number" (Value val)-  numberBinaryPred' (Float _ _)  val           = throwError $ TypeMismatch "float" (Value val)-  numberBinaryPred' val          _             = throwError $ TypeMismatch "number" (Value val)+  numberBinaryPred' (Float f 0)    (Float f' 0)  = return $ Bool $ (>=) f f'+  numberBinaryPred' (ScalarData _) val           = throwError $ TypeMismatch "number" (Value val)+  numberBinaryPred' (Float _ _)    val           = throwError $ TypeMismatch "float" (Value val)+  numberBinaryPred' val            _             = throwError $ TypeMismatch "number" (Value val)    truncate' :: PrimitiveFunc truncate' = oneArg $ \val -> numberUnaryOp' val  where-  numberUnaryOp' (Number (x,0) (x',0)) = return $ Number ((quot x x'), 0) (1,0)-  numberUnaryOp' (Float x y)           = return $ Number ((truncate x), (truncate y)) (1,0)+  numberUnaryOp' (ScalarData (Div (Plus []) _)) = return $ toEgison (0 :: Integer)+  numberUnaryOp' (ScalarData (Div (Plus [(Term x [])]) (Plus [(Term y [])]))) = return $ toEgison (quot x y)+  numberUnaryOp' (Float x _)           = return $ toEgison ((truncate x) :: Integer)   numberUnaryOp' val                   = throwError $ TypeMismatch "ratinal or float" (Value val) +realPart :: PrimitiveFunc+realPart =  oneArg $ realPart'+ where+  realPart' (Float x y) = return $ Float x 0+  realPart' val = throwError $ TypeMismatch "float" (Value val)++imaginaryPart :: PrimitiveFunc+imaginaryPart =  oneArg $ imaginaryPart'+ where+  imaginaryPart' (Float _ y) = return $ Float y 0+  imaginaryPart' val = throwError $ TypeMismatch "float" (Value val)+ --+-- Tensor+--++tensorProd :: PrimitiveFunc+tensorProd = twoArgs $ tensorProd'+ where+  tensorProd' (TensorData (TData (Tensor ns1 xs1) (Just ms1)))+              (TensorData (TData (Tensor ns2 xs2) (Just ms2))) = do+    ret <- tContract (TData (Tensor (ns1 ++ ns2) (map (\is -> let is1 = take (length ns1) is in+                                                              let is2 = take (length ns2) (drop (length ns1) is) in+                                                                (mathMult (tref' is1 (Tensor ns1 xs1)) (tref' is2 (Tensor ns2 xs2)))+                                                       ) (tensorIndices (ns1 ++ ns2)))) (Just (ms1 ++ ms2)))+    return ret+  tensorProd' val1 val2 = throwError $ TypeMismatch "tensor data with index" (Value (Tuple [val1, val2]))++tensorIndex :: PrimitiveFunc+tensorIndex = oneArg $ tensorIndex'+ where+  tensorIndex' (TensorData (TData (Tensor _ _) (Just ms))) = return . Collection . Sq.fromList $ map ScalarData ms+  tensorIndex' val = throwError $ TypeMismatch "tensor with index" (Value val)++tensorSize :: PrimitiveFunc+tensorSize = oneArg $ tensorSize'+ where+  tensorSize' (TensorData (TData (Tensor ns _) _)) = return . Collection . Sq.fromList $ map toEgison ns+  tensorSize' val = throwError $ TypeMismatch "tensor data" (Value val)++tensorToList :: PrimitiveFunc+tensorToList = oneArg $ tensorToList'+ where+  tensorToList' (TensorData (TData (Tensor _ xs) _)) = return . Collection . Sq.fromList $ map ScalarData xs+  tensorToList' val = throwError $ TypeMismatch "tensor data" (Value val)++-- -- Transform -- numberToFloat' :: EgisonValue -> EgisonValue-numberToFloat' (Number (x,y) (d,0)) = Float (fromRational (x % d)) (fromRational (y % d))+numberToFloat' (ScalarData (Div (Plus []) _)) = Float 0 0+numberToFloat' (ScalarData (Div (Plus [(Term x [])]) (Plus [(Term y [])]))) = Float (fromRational (x % y)) 0  integerToFloat :: PrimitiveFunc integerToFloat = rationalToFloat@@ -380,25 +433,30 @@ rationalToFloat :: PrimitiveFunc rationalToFloat = oneArg $ \val ->   case val of-    Number (x,y) (d,0) -> return $ numberToFloat' val-    _ -> throwError $ TypeMismatch "integer of rational number" (Value val)+    (ScalarData (Div (Plus []) _)) -> return $ numberToFloat' val+    (ScalarData (Div (Plus [(Term _ [])]) (Plus [(Term _ [])]))) -> return $ numberToFloat' val+    _ -> throwError $ TypeMismatch "integer or rational number" (Value val)  charToInteger :: PrimitiveFunc charToInteger = oneArg $ \val -> do   case val of-    Char c -> return $ Number ((fromIntegral $ ord c), 0) (1,0)+    Char c -> do+      let i = fromIntegral $ ord c :: Integer+      return $ toEgison i     _ -> throwError $ TypeMismatch "character" (Value val)  integerToChar :: PrimitiveFunc integerToChar = oneArg $ \val -> do   case val of-    (Number (x,0) (1,0)) -> return $ Char $ chr $ fromIntegral x+    (ScalarData _) -> do+       i <- fromEgison val :: EgisonM Integer+       return $ Char $ chr $ fromIntegral i     _ -> throwError $ TypeMismatch "integer" (Value val)  floatToIntegerOp :: (Double -> Integer) -> PrimitiveFunc floatToIntegerOp op = oneArg $ \val -> do   f <- fromEgison val-  return $ Number ((op f), 0) (1,0)+  return $ toEgison (op f)  -- -- String@@ -425,7 +483,7 @@ lengthString :: PrimitiveFunc lengthString = oneArg $ \val -> do   case val of-    String str -> return . (\x -> Number (x,0) (1,0)) . toInteger $ T.length str+    String str -> return . (\x -> toEgison x) . toInteger $ T.length str     _ -> throwError $ TypeMismatch "string" (Value val)  appendString :: PrimitiveFunc@@ -521,57 +579,6 @@     Just (racObjRef, rdcObjRef) -> return $ Intermediate $ ITuple [racObjRef, rdcObjRef]     Nothing -> throwError $ Default $ "cannot unsnoc collection" --- Typing--isBool :: PrimitiveFunc-isBool (Value (Bool _)) = return $ Value $ Bool True-isBool _ = return $ Value $ Bool False--isInteger :: PrimitiveFunc-isInteger (Value (Number (_,0) (1,0))) = return $ Value $ Bool True-isInteger _ = return $ Value $ Bool False--isRational :: PrimitiveFunc-isRational (Value (Number (_, 0) (_, 0))) = return $ Value $ Bool True-isRational _ = return $ Value $ Bool False--isNumber :: PrimitiveFunc-isNumber (Value (Number _ _)) = return $ Value $ Bool True-isNumber _ = return $ Value $ Bool False--isFloat :: PrimitiveFunc-isFloat (Value (Float _ 0)) = return $ Value $ Bool True-isFloat _ = return $ Value $ Bool False--isComplex :: PrimitiveFunc-isComplex (Value (Float _ _)) = return $ Value $ Bool True-isComplex _ = return $ Value $ Bool False--isChar :: PrimitiveFunc-isChar (Value (Char _)) = return $ Value $ Bool True-isChar _ = return $ Value $ Bool False--isString :: PrimitiveFunc-isString (Value (String _)) = return $ Value $ Bool True-isString _ = return $ Value $ Bool False--isCollection :: PrimitiveFunc-isCollection (Value (Collection _)) = return $ Value $ Bool True-isCollection (Intermediate (ICollection _)) = return $ Value $ Bool True-isCollection _ = return $ Value $ Bool False--isArray :: PrimitiveFunc-isArray (Value (Array _)) = return $ Value $ Bool True-isArray (Intermediate (IArray _)) = return $ Value $ Bool True-isArray _ = return $ Value $ Bool False--isHash :: PrimitiveFunc-isHash (Value (IntHash _)) = return $ Value $ Bool True-isHash (Value (StrHash _)) = return $ Value $ Bool True-isHash (Intermediate (IIntHash _)) = return $ Value $ Bool True-isHash (Intermediate (IStrHash _)) = return $ Value $ Bool True-isHash _ = return $ Value $ Bool False- -- Test  assert ::  PrimitiveFunc@@ -704,10 +711,10 @@  randRange :: PrimitiveFunc randRange = twoArgs $ \val val' -> do-  i <- fromEgison val-  i' <- fromEgison val'+  i <- fromEgison val :: EgisonM Integer+  i' <- fromEgison val' :: EgisonM Integer   n <- liftIO $ getStdRandom $ randomR (i, i')-  return $ makeIO $ return $ Number (n,0) (1,0)+  return $ makeIO $ return $ toEgison n   {-- -- for 'egison-sqlite' sqlite :: PrimitiveFunc
hs-src/Language/Egison/Types.hs view
@@ -24,17 +24,44 @@     , PrimitiveDataPattern (..)     -- * Egison values     , EgisonValue (..)+    , ScalarData (..)+    , PolyExpr (..)+    , TermExpr (..)+    , SymbolExpr (..)+    , TensorData (..)+    , Tensor (..)+    , scalarToUnitTensor+    , scalarToTensor+    , tMap+    , tMap2+    , tCheckIndex+    , tContract+    , tref+    , tref'+    , tSize+    , tToList+    , tIndex+    , makeTensor+    , tensorIndices+    , symbolScalarData+    , mathExprToEgison+    , egisonToScalarData+    , mathNormalize'+    , mathFold+    , mathSymbolFold+    , mathTermFold+    , mathRemoveZero+    , mathReduceFraction+    , mathReduceSymbolFraction+    , mathPlus+    , mathMult+    , mathNegate+    , mathNumerator+    , mathDenominator     , Matcher (..)     , PrimitiveFunc (..)     , EgisonData (..)     , showTSV-    , addInteger-    , subInteger-    , mulInteger-    , addInteger'-    , subInteger'-    , mulInteger'-    , reduceFraction     -- * Internal data     , Object (..)     , ObjectRef (..)@@ -81,6 +108,27 @@     , mconcat     , mmap     , mfor+    -- * Typing+    , isBool+    , isInteger+    , isRational+    , isSymbol+    , isNumber+    , isTensor+    , isTensorWithIndex+    , isBool'+    , isInteger'+    , isRational'+    , isNumber'+    , isFloat'+    , isComplex'+    , isTensor'+    , isTensorWithIndex'+    , isChar'+    , isString'+    , isCollection'+    , isArray'+    , isHash'     ) where  import Prelude hiding (foldr, mappend, mconcat)@@ -97,6 +145,7 @@ import Control.Monad.Trans.Maybe  import Data.Monoid (Monoid)+import qualified Data.HashMap.Lazy as HL import qualified Data.Array as Array import qualified Data.Sequence as Sq import Data.Sequence (Seq)@@ -105,7 +154,7 @@ import Data.HashMap.Strict (HashMap) import qualified Data.HashMap.Strict as HashMap -import Data.List (intercalate)+import Data.List (intercalate, sort, sortBy) import Data.Text (Text) import qualified Data.Text as T @@ -126,25 +175,29 @@     -- temporary : we will replace load to import and export   | LoadFile String   | Load String- deriving (Show)+ deriving (Show, Eq)  data EgisonExpr =     CharExpr Char   | StringExpr Text   | BoolExpr Bool-  | NumberExpr (Integer, Integer) (Integer, Integer)+  | IntegerExpr Integer   | FloatExpr Double Double   | VarExpr String   | IndexedExpr EgisonExpr [EgisonExpr]+  | PowerExpr EgisonExpr EgisonExpr   | InductiveDataExpr String [EgisonExpr]   | TupleExpr [EgisonExpr]   | CollectionExpr [InnerExpr]   | ArrayExpr [EgisonExpr]   | HashExpr [(EgisonExpr, EgisonExpr)]+  | TensorExpr EgisonExpr EgisonExpr    | LambdaExpr [String] EgisonExpr   | MemoizedLambdaExpr [String] EgisonExpr   | MemoizeExpr [(EgisonExpr, EgisonExpr, EgisonExpr)] EgisonExpr+  | CambdaExpr String EgisonExpr+  | MacroExpr [String] EgisonExpr   | PatternFunctionExpr [String] EgisonPattern      | IfExpr EgisonExpr EgisonExpr EgisonExpr@@ -164,30 +217,35 @@    | MatcherBFSExpr MatcherInfo   | MatcherDFSExpr MatcherInfo+  | AlgebraicDataMatcherExpr [(String, [EgisonExpr])]      | DoExpr [BindingExpr] EgisonExpr   | IoExpr EgisonExpr        | SeqExpr EgisonExpr EgisonExpr-  | ContExpr   | ApplyExpr EgisonExpr EgisonExpr+  | CApplyExpr EgisonExpr EgisonExpr   | PartialExpr Integer EgisonExpr   | PartialVarExpr Integer   | RecVarExpr -  | AlgebraicDataMatcherExpr [(String, [EgisonExpr])]-  | GenerateArrayExpr [String] EgisonExpr EgisonExpr-  | ArraySizeExpr EgisonExpr+  | GenerateArrayExpr EgisonExpr (EgisonExpr, EgisonExpr)+  | ArrayBoundsExpr EgisonExpr   | ArrayRefExpr EgisonExpr EgisonExpr +  | GenerateTensorExpr EgisonExpr EgisonExpr+  | InitTensorExpr EgisonExpr EgisonExpr EgisonExpr+  | TensorMapExpr EgisonExpr EgisonExpr+  | TensorMap2Expr EgisonExpr EgisonExpr EgisonExpr+   | SomethingExpr   | UndefinedExpr- deriving (Show)+ deriving (Show, Eq)  data InnerExpr =     ElementExpr EgisonExpr   | SubCollectionExpr EgisonExpr- deriving (Show)+ deriving (Show, Eq)  type BindingExpr = ([String], EgisonExpr) type MatchClause = (EgisonPattern, EgisonExpr)@@ -209,29 +267,31 @@   | InductivePat String [EgisonPattern]   | LoopPat String LoopRange EgisonPattern EgisonPattern   | ContPat-  | ApplyPat EgisonExpr [EgisonPattern]+  | PApplyPat EgisonExpr [EgisonPattern]+  | DApplyPat EgisonPattern [EgisonPattern]   | VarPat String- deriving (Show)+ deriving (Show, Eq)  data LoopRange = LoopRange EgisonExpr EgisonExpr EgisonPattern- deriving (Show)+ deriving (Show, Eq)  data PrimitivePatPattern =     PPWildCard   | PPPatVar   | PPValuePat String   | PPInductivePat String [PrimitivePatPattern]- deriving (Show)+ deriving (Show, Eq)  data PrimitiveDataPattern =     PDWildCard   | PDPatVar String   | PDInductivePat String [PrimitiveDataPattern]+  | PDTuplePat [PrimitiveDataPattern]   | PDEmptyPat   | PDConsPat PrimitiveDataPattern PrimitiveDataPattern   | PDSnocPat PrimitiveDataPattern PrimitiveDataPattern   | PDConstantPat EgisonExpr- deriving (Show)+ deriving (Show, Eq)  -- -- Values@@ -242,7 +302,8 @@   | Char Char   | String Text   | Bool Bool-  | Number (Integer, Integer) (Integer, Integer)+  | ScalarData ScalarData+  | TensorData TensorData   | Float Double Double   | InductiveData String [EgisonValue]   | Tuple [EgisonValue]@@ -252,16 +313,385 @@   | CharHash (HashMap Char EgisonValue)   | StrHash (HashMap Text EgisonValue)   | UserMatcher Env PMMode MatcherInfo-  | Func Env [String] EgisonExpr-  | MemoizedFunc ObjectRef (IORef (HashMap [Integer] ObjectRef)) Env [String] EgisonExpr+  | Func (Maybe String) Env [String] EgisonExpr+  | CFunc (Maybe String) Env String EgisonExpr+  | MemoizedFunc (Maybe String) ObjectRef (IORef (HashMap [Integer] ObjectRef)) Env [String] EgisonExpr+  | Macro [String] EgisonExpr   | PatternFunc Env [String] EgisonPattern-  | PrimitiveFunc PrimitiveFunc+  | PrimitiveFunc String PrimitiveFunc   | IOFunc (EgisonM WHNFData)   | Port Handle   | Something   | Undefined   | EOF +--+-- Scalars+--++data ScalarData =+    Div PolyExpr PolyExpr+ deriving (Eq)++data PolyExpr =+    Plus [TermExpr]+ deriving (Eq)++data TermExpr =+    Term Integer [(SymbolExpr, Integer)]+ deriving (Eq)++data SymbolExpr =+    Symbol String [Integer]+  | Apply EgisonValue [ScalarData]+ deriving (Eq)+++symbolScalarData :: String -> [Integer] -> EgisonValue+symbolScalarData name js = (ScalarData (Div (Plus [(Term 1 [(Symbol name js, 1)])]) (Plus [(Term 1 [])])))++mathExprToEgison :: ScalarData -> EgisonValue+mathExprToEgison (Div p1 p2) = InductiveData "Div" [(polyExprToEgison p1), (polyExprToEgison p2)]++polyExprToEgison :: PolyExpr -> EgisonValue+polyExprToEgison (Plus ts) = InductiveData "Plus" [Collection (Sq.fromList (map termExprToEgison ts))]++termExprToEgison :: TermExpr -> EgisonValue+termExprToEgison (Term a xs) = InductiveData "Term" [toEgison a, Collection (Sq.fromList (map symbolExprToEgison xs))]++symbolExprToEgison :: (SymbolExpr, Integer) -> EgisonValue+symbolExprToEgison (Symbol x js, n) = Tuple [InductiveData "Symbol" [toEgison (T.pack x), toEgison js], toEgison n]+symbolExprToEgison (Apply fn mExprs, n) = Tuple [InductiveData "Apply" [fn, Collection (Sq.fromList (map mathExprToEgison mExprs))], toEgison n]++egisonToScalarData :: EgisonValue -> EgisonM ScalarData+egisonToScalarData (InductiveData "Div" [p1, p2]) = Div <$> egisonToPolyExpr p1 <*> egisonToPolyExpr p2+egisonToScalarData p1@(InductiveData "Plus" _) = Div <$> egisonToPolyExpr p1 <*> (return (Plus [(Term 1 [])]))+egisonToScalarData t1@(InductiveData "Term" _) = do+  t1' <- egisonToTermExpr t1+  return $ Div (Plus [t1']) (Plus [(Term 1 [])])+egisonToScalarData s1@(InductiveData "Symbol" _) = do+  s1' <- egisonToSymbolExpr (Tuple [s1, toEgison (1 ::Integer)])+  return $ Div (Plus [(Term 1 [s1'])]) (Plus [(Term 1 [])])+egisonToScalarData s1@(InductiveData "Apply" _) = do+  s1' <- egisonToSymbolExpr (Tuple [s1, toEgison (1 :: Integer)])+  return $ Div (Plus [(Term 1 [s1'])]) (Plus [(Term 1 [])])+egisonToScalarData val = liftError $ throwError $ TypeMismatch "math expression" (Value val)++egisonToPolyExpr :: EgisonValue -> EgisonM PolyExpr+egisonToPolyExpr (InductiveData "Plus" [Collection ts]) = Plus <$> mapM egisonToTermExpr (toList ts)+egisonToPolyExpr val = liftError $ throwError $ TypeMismatch "math poly expression" (Value val)++egisonToTermExpr :: EgisonValue -> EgisonM TermExpr+egisonToTermExpr (InductiveData "Term" [n, Collection ts]) = Term <$> fromEgison n <*> mapM egisonToSymbolExpr (toList ts)+egisonToTermExpr val = liftError $ throwError $ TypeMismatch "math term expression" (Value val)++egisonToSymbolExpr :: EgisonValue -> EgisonM (SymbolExpr, Integer)+egisonToSymbolExpr (Tuple [InductiveData "Symbol" [x, js], n]) = do+  x' <- fromEgison x+  js' <- fromEgison js+  n' <- fromEgison n+  return (Symbol (T.unpack x') js', n')+egisonToSymbolExpr (Tuple [InductiveData "Apply" [fn, (Collection mExprs)], n]) = do+  mExprs' <- mapM egisonToScalarData (toList mExprs)+  n' <- fromEgison n+  return (Apply fn mExprs', n')+egisonToSymbolExpr val = liftError $ throwError $ TypeMismatch "math symbol expression" (Value val)++mathNormalize' :: ScalarData -> ScalarData+mathNormalize' mExpr = mathReduceSymbolFraction (mathReduceFraction (mathRemoveZero (mathFold (mathRemoveZeroSymbol mExpr))))++mathRemoveZeroSymbol :: ScalarData -> ScalarData+mathRemoveZeroSymbol (Div (Plus ts1) (Plus ts2)) =+  let p x = case x of+              (_, 0) -> False+              _ -> True in+  let ts1' = map (\(Term a xs) -> Term a (filter p xs)) ts1 in+  let ts2' = map (\(Term a xs) -> Term a (filter p xs)) ts2 in+    Div (Plus ts1') (Plus ts2')++mathRemoveZero :: ScalarData -> ScalarData+mathRemoveZero (Div (Plus ts1) (Plus ts2)) =+  let ts1' = filter (\(Term a _) -> a /= 0) ts1 in+  let ts2' = filter (\(Term a _) -> a /= 0) ts2 in+    case ts1' of+      [] -> Div (Plus []) (Plus [Term 1 []])+      _ -> Div (Plus ts1') (Plus ts2')++mathReduceFraction :: ScalarData -> ScalarData+mathReduceFraction (Div (Plus []) (Plus ts2)) = Div (Plus []) (Plus ts2)+mathReduceFraction (Div (Plus ts1) (Plus [])) = Div (Plus ts1) (Plus [])+mathReduceFraction (Div (Plus ts1) (Plus ts2)) =+  let as1 = map (\(Term a _) -> a) ts1 in+  let as2 = map (\(Term a _) -> a) ts2 in+  let flg = case as2 of+              [a2] -> if a2 < 0+                        then -1+                        else 1+              _ -> 1 in+  let d = (foldl gcd (head as1) ((tail as1) ++ as2)) * flg in+  let us1 = map (\(Term a xs) -> Term (a `quot` d) xs) ts1 in+  let us2 = map (\(Term a xs) -> Term (a `quot` d) xs) ts2 in+    Div (Plus us1) (Plus us2)++mathReduceSymbolFraction :: ScalarData -> ScalarData+mathReduceSymbolFraction (Div (Plus ts) (Plus ((Term a xs):[]))) = f xs [] ts+ where+  f :: [(SymbolExpr, Integer)] -> [(SymbolExpr, Integer)] -> [TermExpr] -> ScalarData+  f [] ret ts = Div (Plus ts) (Plus [Term a ret])+  f ((x, n):xs) ret ts =+    let k = g x ts in+      if n > k+        then f xs (ret ++ [(x, (n - k))]) (h x k ts)+        else f xs ret (h x n ts)+  g :: SymbolExpr -> [TermExpr] -> Integer+  g x ts = minimum (map (\(Term _ xs) -> g' x xs) ts)+  g' :: SymbolExpr -> [(SymbolExpr, Integer)] -> Integer+  g' x [] = 0+  g' x ((y, n):xs) = if x == y+                       then n+                       else g' x xs+  h :: SymbolExpr -> Integer -> [TermExpr] -> [TermExpr]+  h x k ts = map (\(Term a xs) -> Term a (filter (\(y, n) -> n /= 0)+                                                 (map (\(y, n) -> if x == y+                                                                    then (y, (n - k))+                                                                    else (y, n))+                                                      xs)))+                 ts+mathReduceSymbolFraction mExpr = mExpr++mathFold :: ScalarData -> ScalarData+mathFold mExpr = (mathTermFold (mathSymbolFold (mathTermFold mExpr)))++mathSymbolFold :: ScalarData -> ScalarData+mathSymbolFold (Div (Plus ts1) (Plus ts2)) = Div (Plus (map f ts1)) (Plus (map f ts2))+ where+  f :: TermExpr -> TermExpr+  f (Term a xs) = Term a (g [] xs)+  g :: [(SymbolExpr, Integer)] -> [(SymbolExpr, Integer)] -> [(SymbolExpr, Integer)]+  g ret [] = ret+  g ret ((x, n):xs) =+    if (any (p (x, n)) ret)+      then g (map (h (x, n)) ret) xs+      else g (ret ++ [(x, n)]) xs+  p :: (SymbolExpr, Integer) -> (SymbolExpr, Integer) -> Bool+  p (x, _) (y, _) = x == y+  h :: (SymbolExpr, Integer) -> (SymbolExpr, Integer) -> (SymbolExpr, Integer)+  h (x, n) (y, m) = if x == y+                     then (y, m + n)+                     else (y, m)++mathTermFold :: ScalarData -> ScalarData+mathTermFold (Div (Plus ts1) (Plus ts2)) = Div (Plus (f ts1)) (Plus (f ts2))+ where+  f :: [TermExpr] -> [TermExpr]+  f ts = f' [] ts+  f' :: [TermExpr] -> [TermExpr] -> [TermExpr]+  f' ret [] = ret+  f' ret ((Term a xs):ts) =+    if any (\(Term _ ys) -> (p xs ys)) ret+      then f' (map (g (Term a xs)) ret) ts+      else f' (ret ++ [(Term a xs)]) ts+  g :: TermExpr -> TermExpr -> TermExpr+  g (Term a xs) (Term b ys) = if p xs ys+                                then (Term (a + b) ys)+                                else Term b ys+  p :: [(SymbolExpr, Integer)] -> [(SymbolExpr, Integer)] -> Bool+  p [] [] = True+  p [] _ = False+  p ((x, n):xs) ys =+    let (b, ys') = q (x, n) [] ys in+      if b +        then p xs ys'+        else False+  q :: (SymbolExpr, Integer) -> [(SymbolExpr, Integer)] -> [(SymbolExpr, Integer)] -> (Bool, [(SymbolExpr, Integer)])+  q _ _ [] = (False, [])+  q (x, n) ret ((y, m):ys) = if (x == y) && (n == m)+                               then (True, (ret ++ ys))+                               else q (x, n) (ret ++ [(y, m)]) ys++--+--  Arithmetic operations+--++mathPlus :: ScalarData -> ScalarData -> ScalarData+mathPlus (Div m1 n1) (Div m2 n2) = mathNormalize' $ Div (mathPlusPoly (mathMultPoly m1 n2) (mathMultPoly m2 n1)) (mathMultPoly n1 n2)++mathPlusPoly :: PolyExpr -> PolyExpr -> PolyExpr+mathPlusPoly (Plus ts1) (Plus ts2) = Plus (ts1 ++ ts2)++mathMult :: ScalarData -> ScalarData -> ScalarData+mathMult (Div m1 n1) (Div m2 n2) = mathNormalize' $ Div (mathMultPoly m1 m2) (mathMultPoly n1 n2)++mathMultPoly :: PolyExpr -> PolyExpr -> PolyExpr+mathMultPoly (Plus []) (Plus _) = Plus []+mathMultPoly (Plus _) (Plus []) = Plus []+mathMultPoly (Plus ts1) (Plus ts2) = foldl mathPlusPoly (Plus []) (map (\(Term a xs) -> (Plus (map (\(Term b ys) -> (Term (a * b) (xs ++ ys))) ts2))) ts1)++mathNegate :: ScalarData -> ScalarData+mathNegate (Div m n) = Div (mathNegate' m) n++mathNegate' :: PolyExpr -> PolyExpr+mathNegate' (Plus ts) = Plus (map (\(Term a xs) -> (Term (negate a) xs)) ts)++mathNumerator :: ScalarData -> ScalarData+mathNumerator (Div m _) = Div m (Plus [(Term 1 [])])++mathDenominator :: ScalarData -> ScalarData+mathDenominator (Div _ n) = Div n (Plus [(Term 1 [])])++--+-- Tensors+--++data TensorData =+    TData (Tensor ScalarData) (Maybe [ScalarData])+ deriving (Eq)++data Tensor a = Tensor [Integer] [a]+ deriving (Eq)++scalarToUnitTensor :: [Integer] -> ScalarData -> (Maybe [ScalarData]) -> TensorData+scalarToUnitTensor ns x js = makeTensor ns (map (\ms -> if all (\m -> m == (head ms)) (tail ms)+                                                         then x+                                                         else (Div (Plus []) (Plus [(Term 1 [])]))) (tensorIndices ns))+                                                js++scalarToTensor :: [Integer] -> ScalarData -> (Maybe [ScalarData]) -> TensorData+scalarToTensor ns x js = makeTensor ns (map (\ms -> x) (tensorIndices ns)) js++makeTensor :: [Integer] -> [ScalarData] -> (Maybe [ScalarData]) -> TensorData+makeTensor ns xs js = TData (Tensor ns xs) js++tensorIndices :: [Integer] -> [[Integer]]+tensorIndices [] = [[]]+tensorIndices (n:ns) = concat (map (\i -> (map (\is -> i:is) (tensorIndices ns))) [1..n])++tMap :: (ScalarData -> EgisonM ScalarData) -> TensorData -> EgisonM TensorData+tMap f (TData (Tensor ns xs) js) = do+  xs' <- mapM f xs+  return $ TData (Tensor ns xs') js++tMap2 :: (ScalarData -> ScalarData -> EgisonM ScalarData) -> TensorData -> TensorData -> EgisonM TensorData+tMap2 f (TData t1@(Tensor ns1 xs1) (Just js1)) (TData t2@(Tensor ns2 xs2) (Just js2)) = do+  ns2' <- transIndex js1 js2 ns2+  if ns1 == ns2'+    then do ys <- mapM (\is -> do is' <- transIndex js1 js2 is+                                  f (tref' is t1) (tref' is' t2))+                       (tensorIndices ns1)+            return $ makeTensor ns1 ys (Just js1)+    else throwError $ InconsistentTensorSize+tMap2 f (TData t1@(Tensor ns1 xs1) Nothing) (TData t2@(Tensor ns2 xs2) Nothing) = do+  if ns1 == ns2+    then do ys <- mapM (\is -> f (tref' is t1) (tref' is t2))+                       (tensorIndices ns1)+            return $ makeTensor ns1 ys Nothing+    else throwError $ InconsistentTensorSize+tMap2 _ t1 t2 = do+  throwError $ InconsistentTensorIndex -- TODO : new error type++tSum :: [Tensor ScalarData] -> (Tensor ScalarData)+tSum (t:ts) = tSum' t ts+ where+  tSum' :: (Tensor ScalarData) -> [Tensor ScalarData] -> (Tensor ScalarData)+  tSum' (Tensor ns xs) [] = Tensor ns xs+  tSum' (Tensor ns xs) ((Tensor _ xs1):ts) =+    tSum' (Tensor ns (map (\(x,y) -> mathNormalize' (mathPlus x y)) (zip xs xs1))) ts++transIndex :: [ScalarData] -> [ScalarData] -> [Integer] -> EgisonM [Integer]+transIndex [] [] [] = return []+transIndex (j1:js1) js2 is = do+  let (hjs2, tjs2) = break (\j2 -> j1 == j2) js2+  if tjs2 == []+    then throwError $ InconsistentTensorIndex+    else do let n = (length hjs2) + 1+            rs <- transIndex js1 (hjs2 ++ (tail tjs2)) ((take (n - 1) is) ++ (drop n is))+            return ((is !! (n - 1)):rs)+transIndex _ _ _ = throwError $ InconsistentTensorSize++tContract :: TensorData -> EgisonM EgisonValue+tContract (TData t@(Tensor ns xs) (Just js)) = do+  case (findPairs js) of+    [] -> return $ TensorData (TData (Tensor ns xs) (Just js))+    ((hs,ms,ts):_) -> do+      let hn = (length hs) + 1+      let mn = (length (hs ++ ms)) + 2+      if (ns !! (hn - 1)) == (ns !! (mn - 1))+        then do+          let n = ns !! (hn - 1)+          let ret = TData (tSum (map (\i -> (tref (hs ++ [(Div (Plus [(Term i [])]) (Plus [(Term 1 [])]))] ++ ms+                                                      ++ [(Div (Plus [(Term i [])]) (Plus [(Term 1 [])]))] ++ ts) t))+                                     [1..n]))+                          (Just (hs ++ ms ++ ts))+          case ret of+            (TData (Tensor [] [x]) (Just [])) -> return $ ScalarData x+            _ -> return $ TensorData ret+        else throwError $ InconsistentTensorIndex+ where+  findPairs :: [ScalarData] -> [([ScalarData], [ScalarData], [ScalarData])]+  findPairs xs = findPairs' [] xs+  findPairs' :: [ScalarData] -> [ScalarData] -> [([ScalarData], [ScalarData], [ScalarData])]+  findPairs' _ [] = []+  findPairs' hs (x:xs) = (findPairs'' hs x xs) ++ (findPairs' (hs ++ [x]) xs)+  findPairs'' :: [ScalarData] -> ScalarData -> [ScalarData] -> [([ScalarData], [ScalarData], [ScalarData])]+  findPairs'' hs x xs =+    let (hxs, txs) = break (\e -> e == x) xs in+    if txs == []+      then []+      else [(hs, hxs, (tail txs))]+tContract (TData _ Nothing) = throwError $ InconsistentTensorIndex -- TODO : new error type++tCheckIndex :: [ScalarData] -> [Integer] -> EgisonM ()+tCheckIndex [] [] = return ()+tCheckIndex ((Div (Plus [(Term m [])]) (Plus [(Term 1 [])])):ms) (n:ns) =+  if (0 < m) && (m <= n)+    then tCheckIndex ms ns+    else throwError $ TensorIndexOutOfBounds m n+tCheckIndex (Div (Plus [(Term 1 [(Symbol _ _, 1)])]) (Plus [(Term 1 [])]):ms) (n:ns) = tCheckIndex ms ns+tCheckIndex (m:_) _ = throwError $ TypeMismatch "symbol or natural number" (Value (ScalarData m))++tref' :: [Integer] -> (Tensor a) -> a+tref' ms (Tensor ns xs) = tref'' ms ns xs+ where+  tref'' :: [Integer] -> [Integer] -> [a] -> a+  tref'' [m] [n] xs = xs !! (fromIntegral (m - 1))+  tref'' (m:ms) (n:ns) xs =+    let w = fromIntegral (product ns) in+    let ys = take w (drop (w * (fromIntegral (m - 1))) xs) in+      tref'' ms ns ys++tref :: [ScalarData] -> (Tensor a) -> (Tensor a)+tref ms (Tensor ns xs) = let rns = map snd (filter (\(m,_) -> (isSymbol (ScalarData m))) (zip ms ns)) in+                         let rxs = tsub' ms ns xs in+                           Tensor rns rxs+ where+  tsub' :: [ScalarData] -> [Integer] -> [a] -> [a]+  tsub' [] [] rs = rs+  tsub' (m:ms) (n:ns) xs =+    if isSymbol (ScalarData m)+      then let w = fromIntegral (product ns) in+           let yss = split w xs in+             concat (map (\ys -> tsub' ms ns ys) yss)+      else let i = extractInteger m in+           let w = fromIntegral (product ns) in+           let ys = take w (drop (w * (fromIntegral (i - 1))) xs) in+             tsub' ms ns ys+  split :: Int -> [a] -> [[a]]+  split _ [] = [[]]+  split w xs = let (hs, ts) = splitAt w xs in+                 hs:(split w ts)+  extractInteger :: ScalarData -> Integer+  extractInteger (Div (Plus []) (Plus [(Term 1 [])])) = 0+  extractInteger (Div (Plus [(Term i [])]) (Plus [(Term 1 [])])) = i++tSize :: TensorData -> [Integer]+tSize (TData (Tensor ns _) _) = ns++tToList :: (Tensor a) -> [a]+tToList (Tensor _ xs) = xs++tIndex :: TensorData -> Maybe [ScalarData]+tIndex (TData (Tensor _ _) js) = js+ type Matcher = EgisonValue  type PrimitiveFunc = WHNFData -> EgisonM WHNFData@@ -271,8 +701,8 @@   show (String str) = "\"" ++ T.unpack str ++ "\""   show (Bool True) = "#t"   show (Bool False) = "#f"-  show (Number (x,y) (1,0)) = showComplex x y-  show (Number (x,y) (x',y')) = showComplex x y ++ "/" ++ showComplex x' y'+  show (ScalarData mExpr) = show mExpr+  show (TensorData tExpr) = show tExpr   show (Float x y) = showComplexFloat x y   show (InductiveData name []) = "<" ++ name ++ ">"   show (InductiveData name vals) = "<" ++ name ++ " " ++ unwords (map show vals) ++ ">"@@ -286,10 +716,15 @@   show (StrHash hash) = "{|" ++ unwords (map (\(key, val) -> "[\"" ++ T.unpack key ++ "\" " ++ show val ++ "]") $ HashMap.toList hash) ++ "|}"   show (UserMatcher _ BFSMode _) = "#<matcher-bfs>"   show (UserMatcher _ DFSMode _) = "#<matcher-dfs>"-  show (Func _ names _) = "(lambda [" ++ unwords names ++ "] ...)"-  show (MemoizedFunc _ _ _ names _) = "(memoized-lambda [" ++ unwords names ++ "] ...)"+  show (Func Nothing _ names _) = "(lambda [" ++ unwords names ++ "] ...)"+  show (Func (Just name) _ _ _) = name+  show (CFunc Nothing _ name _) = "(cambda " ++ name ++ " ...)"+  show (CFunc (Just name) _ _ _) = name+  show (MemoizedFunc Nothing _ _ _ names _) = "(memoized-lambda [" ++ unwords names ++ "] ...)"+  show (MemoizedFunc (Just name) _ _ _ names _) = name+  show (Macro names _) = "(macro [" ++ unwords names ++ "] ...)"   show (PatternFunc _ _ _) = "#<pattern-function>"-  show (PrimitiveFunc _) = "#<primitive-function>"+  show (PrimitiveFunc name _) = "#<primitive-function " ++ name ++ ">"   show (IOFunc _) = "#<io-function>"   show (Port _) = "#<port>"   show Something = "something"@@ -297,23 +732,29 @@   show World = "#<world>"   show EOF = "#<eof>" -addInteger :: EgisonValue -> EgisonValue -> EgisonValue-addInteger (Number (x,y) (1,0)) (Number (x',y') (1,0)) = Number ((x+x'),(y+y')) (1,0)--subInteger :: EgisonValue -> EgisonValue -> EgisonValue-subInteger (Number (x,y) (1,0)) (Number (x',y') (1,0)) = Number ((x-x'),(y-y')) (1,0)+instance Show ScalarData where+  show (Div p1 (Plus [(Term 1 [])])) = show p1+  show (Div p1 p2) = "(/ " ++ show p1 ++ " " ++ show p2 ++ ")" -mulInteger :: EgisonValue -> EgisonValue -> EgisonValue-mulInteger (Number (x,y) (1,0)) (Number (x',y') (1,0)) = Number ((x*x'-y*y'),(x*y'+x'*y)) (1,0)+instance Show PolyExpr where+  show (Plus []) = "0"+  show (Plus [t]) = show t+  show (Plus ts) = "(+ " ++ unwords (map show ts)  ++ ")" -addInteger' :: (Integer, Integer) -> (Integer, Integer) -> (Integer, Integer)-addInteger' (x,y) (x',y') = ((x+x'),(y+y'))+instance Show TermExpr where+  show (Term a []) = show a+  show (Term 1 [x]) = showPoweredSymbol x+  show (Term 1 xs) = "(* " ++ unwords (map showPoweredSymbol xs) ++ ")"+  show (Term a xs) = "(* " ++ show a ++ " " ++ unwords (map showPoweredSymbol xs) ++ ")" -subInteger' :: (Integer, Integer) -> (Integer, Integer) -> (Integer, Integer)-subInteger' (x,y) (x',y') = ((x-x'),(y-y'))+showPoweredSymbol :: (SymbolExpr, Integer) -> String+showPoweredSymbol (x, 1) = show x+showPoweredSymbol (x, n) = show x ++ "^" ++ show n -mulInteger' :: (Integer, Integer) -> (Integer, Integer) -> (Integer, Integer)-mulInteger' (x,y) (x',y') = ((x*x'-y*y'),(x*y'+x'*y))+instance Show SymbolExpr where+  show (Symbol s []) = s+  show (Symbol s js) = s ++ unwords' (map show js)+  show (Apply fn mExprs) = "(" ++ show fn ++ " " ++ unwords (map show mExprs) ++ ")"  showComplex :: (Num a, Eq a, Ord a, Show a) => a -> a -> String showComplex x 0 = show x@@ -323,20 +764,19 @@ showComplexFloat :: Double -> Double -> String showComplexFloat x 0.0 = showFFloat Nothing x "" showComplexFloat 0.0 y = showFFloat Nothing y "i"-showComplexFloat x y = (showFFloat Nothing x "") ++ (if y > 0 then "+" else "") ++ (showFFloat Nothing y "i")+showComplexFloat x y = showFFloat Nothing x "" ++ if y > 0 then "+" else "" ++ showFFloat Nothing y "i" -reduceFraction :: EgisonValue -> EgisonValue-reduceFraction (Number (x,y) (x',y'))-    | x' < 0  = let m = negate (foldl gcd x [y, x', y']) in-                  Number (x `quot` m, y `quot` m) (x' `quot` m, y' `quot` m)-    | x' > 0  = let m = foldl gcd x [y, x', y'] in-                  Number (x `quot` m, y `quot` m) (x' `quot` m, y' `quot` m)-    | x' == 0 && y' < 0  = let m = negate (foldl gcd x [y, x', y']) in-                             Number (x `quot` m, y `quot` m) (x' `quot` m, y' `quot` m)-    | x' == 0 && y' > 0  = let m = foldl gcd x [y, x', y'] in-                             Number (x `quot` m, y `quot` m) (x' `quot` m, y' `quot` m)-    | x' == 0 && y' == 0 = Number (1,0) (0,0)+instance Show TensorData where+  show (TData xs Nothing) = show xs+  show (TData xs (Just indices)) = show xs ++ unwords' (map show indices) +unwords' [] = ""+unwords' (x:xs) = "_" ++ x ++ unwords' xs++instance Show (Tensor ScalarData) where+  show (Tensor ns xs) =  "(| {" ++ unwords (map show ns) ++ "} {" ++ unwords (map show xs) ++ "} |)"++ showTSV :: EgisonValue -> String showTSV (Tuple (val:vals)) = foldl (\r x -> r ++ "\t" ++ x) (show val) (map showTSV vals) showTSV (Collection vals) = intercalate "\t" (map showTSV (toList vals))@@ -346,7 +786,8 @@  (Char c) == (Char c') = c == c'  (String str) == (String str') = str == str'  (Bool b) == (Bool b') = b == b'- (Number (x1,y1) (x1',y1')) == (Number (x2,y2) (x2',y2')) = (x1 == x2) && (y1 == y2) && (x1' == x2') && (y1' == y2')+ (ScalarData x) == (ScalarData y) = (x == y)+ (TensorData x) == (TensorData y) = (x == y)  (Float x y) == (Float x' y') = (x == x') && (y == y')  (InductiveData name vals) == (InductiveData name' vals') = (name == name') && (vals == vals')  (Tuple vals) == (Tuple vals') = vals == vals'@@ -355,6 +796,13 @@  (IntHash vals) == (IntHash vals') = vals == vals'  (CharHash vals) == (CharHash vals') = vals == vals'  (StrHash vals) == (StrHash vals') = vals == vals'+ (PrimitiveFunc name1 _) == (PrimitiveFunc name2 _) = name1 == name2+ -- Temporary: searching a better solution+ (Func Nothing _ xs1 expr1) == (Func Nothing _ xs2 expr2) = (xs1 == xs2) && (expr1 == expr2)+ (Func (Just name1) _ _ _) == (Func (Just name2) _ _ _) = name1 == name2+ (CFunc Nothing _ x1 expr1) == (CFunc Nothing _ x2 expr2) = (x1 == x2) && (expr1 == expr2)+ (CFunc (Just name1) _ _ _) == (CFunc (Just name2) _ _ _) = name1 == name2+ (Macro xs1 expr1) == (Macro xs2 expr2) = (xs1 == xs2) && (expr1 == expr2)  _ == _ = False  --@@ -377,11 +825,12 @@   fromEgison = liftError . fromBoolValue  instance EgisonData Integer where-  toEgison i = Number (i, 0) (1, 0)+  toEgison 0 = ScalarData $ mathNormalize' (Div (Plus []) (Plus [(Term 1 [])]))+  toEgison i = ScalarData $ mathNormalize' (Div (Plus [(Term i [])]) (Plus [(Term 1 [])]))   fromEgison = liftError . fromIntegerValue  instance EgisonData Rational where-  toEgison r = Number ((numerator r), 0) ((denominator r), 0)+  toEgison r = ScalarData $ mathNormalize' (Div (Plus [(Term (numerator r) [])]) (Plus [(Term (denominator r) [])]))   fromEgison = liftError . fromRationalValue  instance EgisonData Double where@@ -439,11 +888,13 @@ fromBoolValue val = throwError $ TypeMismatch "bool" (Value val)  fromIntegerValue :: EgisonValue -> Either EgisonError Integer-fromIntegerValue (Number (x, 0) (1, 0)) = return x+fromIntegerValue (ScalarData (Div (Plus []) (Plus [(Term 1 [])]))) = return 0+fromIntegerValue (ScalarData (Div (Plus [(Term x [])]) (Plus [(Term 1 [])]))) = return x fromIntegerValue val = throwError $ TypeMismatch "integer" (Value val)  fromRationalValue :: EgisonValue -> Either EgisonError Rational-fromRationalValue (Number (x, 0) (y, 0)) = return (x % y)+fromRationalValue (ScalarData (Div (Plus []) _)) = return 0+fromRationalValue (ScalarData (Div (Plus [(Term x [])]) (Plus [(Term y [])]))) = return (x % y) fromRationalValue val = throwError $ TypeMismatch "rational" (Value val)  fromFloatValue :: EgisonValue -> Either EgisonError Double@@ -519,9 +970,6 @@ instance EgisonWHNF Integer where   fromWHNF = liftError . fromIntegerWHNF   -instance EgisonWHNF Rational where-  fromWHNF = liftError . fromRationalWHNF-   instance EgisonWHNF Double where   fromWHNF = liftError . fromFloatWHNF   @@ -541,13 +989,10 @@ fromBoolWHNF whnf = throwError $ TypeMismatch "bool" whnf  fromIntegerWHNF :: WHNFData -> Either EgisonError Integer-fromIntegerWHNF (Value (Number (x, 0) (1, 0))) = return x+fromIntegerWHNF (Value (ScalarData (Div (Plus []) (Plus [(Term 1 [])])))) = return 0+fromIntegerWHNF (Value (ScalarData (Div (Plus [(Term x [])]) (Plus [(Term 1 [])])))) = return x fromIntegerWHNF whnf = throwError $ TypeMismatch "integer" whnf -fromRationalWHNF :: WHNFData -> Either EgisonError Rational-fromRationalWHNF (Value (Number (x, 0) (y, 0))) = return (x % y)-fromRationalWHNF whnf = throwError $ TypeMismatch "rational" whnf- fromFloatWHNF :: WHNFData -> Either EgisonError Double fromFloatWHNF (Value (Float f 0)) = return f fromFloatWHNF whnf = throwError $ TypeMismatch "float" whnf@@ -564,19 +1009,20 @@ -- Environment -- -type Env = [HashMap Var ObjectRef]+data Env = Env [HashMap Var ObjectRef]+ deriving (Show)+ type Var = String type Binding = (Var, ObjectRef)  nullEnv :: Env-nullEnv = []+nullEnv = Env []  extendEnv :: Env -> [Binding] -> Env-extendEnv env = (: env) . HashMap.fromList+extendEnv (Env env) = Env . (: env) . HashMap.fromList -refVar :: Env -> Var -> EgisonM ObjectRef-refVar env var = maybe (throwError $ UnboundVariable var) return-                       (msum $ map (HashMap.lookup var) env)+refVar :: Env -> Var -> Maybe ObjectRef+refVar (Env env) var = msum $ map (HashMap.lookup var) env  -- -- Pattern Match@@ -615,6 +1061,9 @@   | ArgumentsNumWithNames [String] Int Int   | ArgumentsNumPrimitive Int Int   | ArgumentsNum Int Int+  | InconsistentTensorSize+  | InconsistentTensorIndex+  | TensorIndexOutOfBounds Integer Integer   | NotImplemented String   | Assertion String   | Match String@@ -635,6 +1084,9 @@                                               show expected ++ ", but got " ++  show got   show (ArgumentsNum expected got) = "Wrong number of arguments: expected " ++                                       show expected ++ ", but got " ++  show got+  show InconsistentTensorSize = "Inconsistent tensor size"+  show InconsistentTensorIndex = "Inconsistent tensor index"+  show (TensorIndexOutOfBounds m n) = "Tensor index out of bounds: " ++ show m ++ ", " ++ show n   show (NotImplemented message) = "Not implemented: " ++ message   show (Assertion message) = "Assertion failed: " ++ message   show (Desugar message) = "Error: " ++ message@@ -771,3 +1223,89 @@  mfor :: Monad m => MList m a -> (a -> m b) -> m (MList m b) mfor = flip mmap++-- Typing++isBool :: EgisonValue -> Bool+isBool (Bool _) = True+isBool _ = False++isBool' :: PrimitiveFunc+isBool' (Value val) = return $ Value $ Bool $ isBool val++isInteger :: EgisonValue -> Bool+isInteger (ScalarData (Div (Plus []) (Plus [(Term 1 [])]))) = True+isInteger (ScalarData (Div (Plus [(Term _ [])]) (Plus [(Term 1 [])]))) = True+isInteger _ = False++isInteger' :: PrimitiveFunc+isInteger' (Value val) = return $ Value $ Bool $ isInteger val++isRational :: EgisonValue -> Bool+isRational (ScalarData (Div (Plus []) (Plus [(Term _ [])]))) = True+isRational (ScalarData (Div (Plus [(Term _ [])]) (Plus [(Term _ [])]))) = True+isRational _ = False++isRational' :: PrimitiveFunc+isRational' (Value val) = return $ Value $ Bool $ isRational val++isSymbol :: EgisonValue -> Bool+isSymbol (ScalarData (Div (Plus [(Term 1 [(Symbol _ _, 1)])]) (Plus [(Term 1 [])]))) = True+isSymbol _ = False++isNumber :: EgisonValue -> Bool+isNumber (ScalarData _) = True+isNumber _ = False++isNumber' :: PrimitiveFunc+isNumber' (Value val) = return $ Value $ Bool $ isNumber val+isNumber' _ = return $ Value $ Bool False++isTensor :: EgisonValue -> Bool+isTensor (TensorData _) = True+isTensor _ = False++isTensor' :: PrimitiveFunc+isTensor' (Value val) = return $ Value $ Bool $ isTensor val+isTensor' _ = return $ Value $ Bool False++isTensorWithIndex :: EgisonValue -> Bool+isTensorWithIndex (TensorData (TData (Tensor _ _) (Just ms))) = True+isTensorWithIndex _ = False++isTensorWithIndex' :: PrimitiveFunc+isTensorWithIndex' (Value val) = return $ Value $ Bool $ isTensorWithIndex val+isTensorWithIndex' _ = return $ Value $ Bool False++isFloat' :: PrimitiveFunc+isFloat' (Value (Float _ 0)) = return $ Value $ Bool True+isFloat' _ = return $ Value $ Bool False++isComplex' :: PrimitiveFunc+isComplex' (Value (Float _ _)) = return $ Value $ Bool True+isComplex' _ = return $ Value $ Bool False++isChar' :: PrimitiveFunc+isChar' (Value (Char _)) = return $ Value $ Bool True+isChar' _ = return $ Value $ Bool False++isString' :: PrimitiveFunc+isString' (Value (String _)) = return $ Value $ Bool True+isString' _ = return $ Value $ Bool False++isCollection' :: PrimitiveFunc+isCollection' (Value (Collection _)) = return $ Value $ Bool True+isCollection' (Intermediate (ICollection _)) = return $ Value $ Bool True+isCollection' _ = return $ Value $ Bool False++isArray' :: PrimitiveFunc+isArray' (Value (Array _)) = return $ Value $ Bool True+isArray' (Intermediate (IArray _)) = return $ Value $ Bool True+isArray' _ = return $ Value $ Bool False++isHash' :: PrimitiveFunc+isHash' (Value (IntHash _)) = return $ Value $ Bool True+isHash' (Value (StrHash _)) = return $ Value $ Bool True+isHash' (Intermediate (IIntHash _)) = return $ Value $ Bool True+isHash' (Intermediate (IStrHash _)) = return $ Value $ Bool True+isHash' _ = return $ Value $ Bool False
− lib/core/array.egi
@@ -1,13 +0,0 @@-;;;;;-;;;;;-;;;;; Array-;;;;;-;;;;;--(define $A.map-  (lambda [$f $a]-    (generate-array [$i] (array-size a) (f a_i))))--(define $A.update-  (lambda [$f $i $a]-    (generate-array [$j] (array-size a) (if (eq? j i) (f a_j) a_j))))
+ lib/core/assoc.egi view
@@ -0,0 +1,107 @@+;;;;;+;;;;;+;;;;; Assoc-Collection+;;;;;+;;;;;++(define $to-assoc+  (lambda [$xs]+    (match xs (list something)+      {[<nil> {}]+       [<cons $x (loop $i [2 $n]+                   <cons ,x ...>+                   (& !<cons ,x _> $rs))>+        {[x n] @(to-assoc rs)}]})))++(define $from-assoc+  (lambda [$xs]+    (match xs (list [something integer])+      {[<nil> {}]+       [<cons [$x $n] $rs>+        {@(take n (repeat1 x)) @(from-assoc rs)}]})))++;;;+;;; Assoc List+;;;++(define $assoc-list+  (lambda [$a]+    (matcher+      {[<nil> []+        {[{} {[]}]+         [_ {}]}]+       [<cons $ $> [a (assoc-list a)]+        {[$tgt (match tgt (list [something integer])+                 {[<cons [$x ,1] $rs> {[x rs]}]+                  [<cons [$x $n] $rs> {[x {[x (- n 1)] @rs}]}]+                  [_ {}]})]}]+       [<ncons ,$k $ $> [a (assoc-list a)]+        {[$tgt (match tgt (list [something integer])+                 {[<cons [$x ,k] $rs> {[x rs]}]+                  [<cons [$x (& ?(gt? $ k) $n)] $rs> {[x {[x (- n k)] @rs}]}]+                  [_ {}]})]}]+       [<ncons $ $ $> [integer a (assoc-list a)]+        {[$tgt (match tgt (list [something integer])+                 {[<cons [$x $k] $rs> {[k x rs]}]+                  [_ {}]})]}]+       [,$val []+        {[$tgt (if (eq? val tgt) {[]} {})]}]+       [$ [something]+        {[$tgt {tgt}]}]+       })))++;;;+;;; Assoc Multiset+;;;++(define $assoc-multiset+  (lambda [$a]+    (matcher+      {[<nil> []+        {[{} {[]}]+         [_ {}]}]+       [<cons ,$x $> [(assoc-multiset a)]+        {[$tgt (match-all tgt (list [a integer])+                 [<join $hs <cons [,x $n] $ts>>+                  (if (eq? n 1)+                    {@hs @ts}+                    {@hs [x (- n 1)] @ts})])]}]+       [<cons $ $> [a (assoc-multiset a)]+        {[$tgt (match-all tgt (list [a integer])+                 [<join $hs <cons [$x $n] $ts>>+                  (if (eq? n 1)+                    [x {@hs @ts}]+                    [x {@hs [x (- n 1)] @ts}])])]}]+       [<ncons ,$n ,$x $> [(assoc-multiset a)]+        {[$tgt (match-all tgt (list [a integer])+                 [<join $hs <cons [,x (& ?(gte? $ n) $k)] $ts>>+                  (if (eq? (- k n) 0)+                    {@hs @ts}+                    {@hs [x (- k n)] @ts})])]}]+       [<ncons ,$n $ $> [a (assoc-multiset a)]+        {[$tgt (match-all tgt (list [a integer])+                 [<join $hs <cons [$x (& ?(gte? $ n) $k)] $ts>>+                  (if (eq? (- k n) 0)+                    [x {@hs @ts}]+                    [x {@hs [x (- k n)] @ts}])])]}]+       [<ncons $ ,$x $> [integer (assoc-multiset a)]+        {[$tgt (match-all tgt (list [a integer])+                 [<join $hs <cons [,x $n] $ts>>+                  [n {@hs @ts}]])]}]+       [<ncons $ $ $> [integer a (assoc-multiset a)]+        {[$tgt (match-all tgt (list [a integer])+                 [<join $hs <cons [$x $n] $ts>>+                  [n x {@hs @ts}]])]}]+       [$ [something]+        {[$tgt {tgt}]}]+       })))++(define $AC.intersect+  (lambda [$xs $ys]+    (match-all [xs ys] [(assoc-multiset something) (assoc-multiset something)]+      [[<ncons $m $x _> <ncons $n ,x _>] [x (min m n)]])))++(define $AC.intersect/m+  (lambda [$a $xs $ys]+    (match-all [xs ys] [(assoc-multiset a) (assoc-multiset a)]+      [[<ncons $m $x _> <ncons $n ,x _>] [x (min m n)]])))
lib/core/collection.egi view
@@ -183,16 +183,47 @@        [[<cons $x $xs2> <cons $y $ys2>]         {(fn x y) @(map2 fn xs2 ys2)}]}))) +(define $map3+  (lambda [$fn $xs $ys $zs]+    (match [xs ys zs] [(list something) (list something) (list something)]+      {[[<nil> _ _] {}]+       [[_ <nil> _] {}]+       [[_ _ <nil>] {}]+       [[<cons $x $xs2> <cons $y $ys2> <cons $z $zs2>]+        {(fn x y z) @(map3 fn xs2 ys2 zs2)}]})))++(define $map4+  (lambda [$fn $xs $ys $zs $ws]+    (match [xs ys zs ws] [(list something) (list something) (list something) (list something)]+      {[[<nil> _ _ _] {}]+       [[_ <nil> _ _] {}]+       [[_ _ <nil> _] {}]+       [[_ _ _ <nil>] {}]+       [[<cons $x $xs2> <cons $y $ys2> <cons $z $zs2> <cons $w $ws2>]+        {(fn x y z w) @(map4 fn xs2 ys2 zs2 ws2)}]})))+ (define $filter   (lambda [$pred $xs]     (foldr (lambda [$y $ys] (if (pred y) {y @ys} ys))            {}            xs))) +(define $partition+  (lambda [$pred $xs]+    [(filter pred xs) (filter 1#(not (pred %1)) xs)]))+ (define $zip   (lambda [$xs $ys]     (map2 (lambda [$x $y] [x y]) xs ys))) +(define $zip3+  (lambda [$xs $ys $zs]+    (map3 (lambda [$x $y $z] [x y z]) xs ys zs)))++(define $zip4+  (lambda [$xs $ys $zs $ws]+    (map4 (lambda [$x $y $z $w] [x y z w]) xs ys zs ws)))+ (define $lookup   (lambda [$k $ls]     (match ls (list [something something])@@ -213,12 +244,25 @@         (let {[$z (fn init x)]}           (seq z (foldl fn z xs)))]}))) +(define $reduce+  (lambda [$fn $ls]+    (foldl fn (car ls) (cdr ls))))+ (define $scanl   (lambda [$fn $init $ls]     {init @(match ls (list something)              {[<nil> {}]               [<cons $x $xs> (scanl fn (fn init x) xs)]})})) +(define $iterate+  (lambda [$fn $x]+    (let* {[$nx1 (fn x)]+           [$nx2 (fn nx1)]+           [$nx3 (fn nx2)]+           [$nx4 (fn nx3)]+           [$nx5 (fn nx4)]}+      {x nx1 nx2 nx3 nx4 @(iterate fn nx5)})))+ (define $append   (lambda [$xs $ys]     {@xs @ys}))@@ -415,14 +459,14 @@   (lambda [$xs $ys]     {@xs      @(match-all [ys xs] [(multiset something) (multiset something)]-        [[<cons $y _> ^<cons ,y _>] y])+        [[<cons $y _> !<cons ,y _>] y])      }))  (define $union/m   (lambda [$a $xs $ys]     {@xs      @(match-all [ys xs] [(multiset a) (multiset a)]-        [[<cons $y _> ^<cons ,y _>] y])+        [[<cons $y _> !<cons ,y _>] y])      }))  (define $intersect@@ -517,7 +561,7 @@ (define $unique   (lambda [$xs]     (match-all (sort xs) (list something)-      [<join _ <cons $x ^<cons ,x _>>> x])))+      [<join _ <cons $x !<cons ,x _>>> x])))  (define $unique/m   (lambda [$a $xs]
lib/core/number.egi view
@@ -51,19 +51,12 @@ (define $prime-factorization   (match-lambda integer     {[,1 {}]+     [(& ?(lt? $ 0) $n) {-1 @(prime-factorization (neg n))}]      [$n (let {[$p (find-factor n)]}            {p @(prime-factorization (quotient n p))})]}))  (define $p-f prime-factorization) -(define $n-adic-  (lambda [$n $x]-    (if (eq? x 0)-      {}-      (let {[$q (quotient x n)]-            [$r (remainder x n)]}-        {@(n-adic n q) r}))))- (define $even?   (lambda [$n]     (eq? 0 (modulo n 2))))@@ -72,18 +65,6 @@   (lambda [$n]     (eq? 1 (modulo n 2)))) -(define $square?-  (lambda [$n]-    (let {[$x (round (sqrt n))]}-      (eq? n (power x 2)))))--(define $gcd-  (lambda [$ns]-    (match ns (multiset integer)-      {[<cons $n <nil>> n]-       [<cons (& ,(min ns) $m) $rs>-        (gcd {m @(delete 0 (map (lambda [$r] (modulo r m)) rs))})]})))- (define $fact   (lambda [$n]     (foldl * 1 (between 1 n))))@@ -97,6 +78,14 @@     (/ (perm n r)        (fact r)))) +(define $n-adic+  (lambda [$n $x]+    (if (eq? x 0)+      {}+      (let {[$q (quotient x n)]+            [$r (remainder x n)]}+        {@(n-adic n q) r}))))+ ;;; ;;; Integers ;;;@@ -111,17 +100,12 @@         {[$tgt {tgt}]}]        }))) -(define $power-  (lambda [$x $n]-    (foldl * 1 (take n (repeat1 x)))))--(define $sum-  (lambda [$xs]-    (foldl + 0 xs)))--(define $product-  (lambda [$xs]-    (foldl * 1 xs)))+;;;+;;; Floats+;;;+(define $exp2+  (lambda [$x $y]+    (exp (* (log x) y))))  ;;; ;;; Decimal Fractions@@ -178,7 +162,7 @@  (define $regular-continued-fraction-of-sqrt-helper   (lambda [$m $a $b] ; a+b*rt(m)-    (let* {[$n (floor (+ (rtof a) (* (rtof b) (sqrt m))))]+    (let* {[$n (floor (+ (rtof a) (* (rtof b) (sqrt (rtof m)))))]            [$x (- m (power n 2))]}       (if (eq? x 0)         {[a b n]}@@ -187,7 +171,7 @@  (define $regular-continued-fraction-of-sqrt   (lambda [$m]-    (let* {[$n (floor (sqrt m))]+    (let* {[$n (floor (sqrt (rtof m)))]            [$x (- m (power n 2))]}       ; n+rt(m)-n       ; n+(rt(m)-n)*(rt(m)+n)/(rt(m)+n)@@ -198,7 +182,7 @@  (define $regular-continued-fraction-of-sqrt'   (lambda [$m]-    (let* {[$n (floor (sqrt m))]+    (let* {[$n (floor (sqrt (rtof m)))]            [$x (- m (power n 2))]}       (if (eq? x 0)         [n {} {}]
lib/core/order.egi view
@@ -27,41 +27,24 @@        [[<cons $x $xs> <cons ,x $ys>] (compare-c xs ys)]        [[<cons $x _> <cons $y _>] (compare x y)]}))) -(define $min-  (lambda [$ns]-    (foldl 2#(if (lt? %1 %2) %1 %2) (car ns) (cdr ns))))--(define $max-  (lambda [$ns]-    (foldl 2#(if (gt? %1 %2) %1 %2) (car ns) (cdr ns))))+(define $b.min+  (lambda [$x $y]+    (if (lt? x y) x y))) -(define $min-and-max-  (lambda [$ns]-    (foldl (lambda [$ret $x]-             (match ret [integer integer]-               {[[$min $max] (if (lt? x min) [x max]-                               (if (gt? x min) [min x]-                                 [min max]))]}))-           [(car ns) (car ns)]-           (cdr ns))))+(define $b.max+  (lambda [$x $y]+    (if (gt? x y) x y)))  (define $min/fn-  (lambda [$compare $ns]-    (foldl 2#(if (eq? (compare %1 %2) <Less>) %1 %2) (car ns) (cdr ns))))+  (lambda [$compare $x $y]+    (if (eq? (compare x y) <Less>) x y)))  (define $max/fn-  (lambda [$compare $ns]-    (foldl 2#(if (eq? (compare %1 %2) <Greater>) %1 %2) (car ns) (cdr ns))))+  (lambda [$compare $x $y]+    (if (eq? (compare x y) <Greater>) x y))) -(define $min-and-max/fn-  (lambda [$compare $ns]-    (foldl (lambda [$ret $x]-             (match ret [integer integer]-               {[[$min $max] (if (eq? (compare x min) <Less>) [x max]-                               (if (eq? (compare x min) <Greater>) [min x]-                                 [min max]))]}))-           [(car ns) (car ns)]-           (cdr ns))))+(define $min (cambda $xs (foldl b.min (car xs) (cdr xs))))+(define $max (cambda $xs (foldl b.max (car xs) (cdr xs))))  (define $split-by-ordering (split-by-ordering/fn compare $ $)) 
lib/core/random.egi view
@@ -2,6 +2,10 @@ ;;;;; Random ;;;;; +(define $rands+  (lambda [$s $e]+    {(pure-rand s e) @(rands s e)}))+ (define $pure-rand   (lambda [$s $e]     (io (rand s e))))
lib/core/string.egi view
@@ -20,12 +20,12 @@                {(uncons-string tgt)})]}]      [<join $ <cons ,$px $>> [string string]       {[$tgt (match-all (S.split (pack {px}) tgt) (list string)-               [<join (& ^<nil> $xs) (& ^<nil> $ys)> [(S.intercalate (pack {px}) xs)+               [<join (& !<nil> $xs) (& !<nil> $ys)> [(S.intercalate (pack {px}) xs)                                 (S.intercalate (pack {px}) ys)                                 ]])]}]      [<join $ <join ,$pxs $>> [string string]       {[$tgt (match-all (S.split pxs tgt) (list string)-               [<join (& ^<nil> $xs) (& ^<nil> $ys)> [(S.intercalate pxs xs)+               [<join (& !<nil> $xs) (& !<nil> $ys)> [(S.intercalate pxs xs)                                 (S.intercalate pxs ys)                                 ]])]}]      [<join $ $> [string string]
+ lib/math/algebra/equations.egi view
@@ -0,0 +1,62 @@+;;;;;+;;;;;+;;;;; Equations+;;;;;+;;;;;++(define $solve1+  (lambda [$f $expr $x]+    (inverse expr f x)))++(define $solve+  (lambda [$eqs]+    (solve' eqs {})))++(define $solve'+  (lambda [$eqs $rets]+    (match eqs (list [math-expr math-expr symbol-expr])+      {[<nil> rets]+       [<cons [$f $expr $x] $rs>+        (solve' rs {@rets [x (solve1 (substitute rets f) (substitute rets expr) x)]})]})))++;;;+;;; Quadratic Equations+;;;+(define $quadratic-formula q-f)++(define $q-f+  (lambda [$f $x]+    (match (coefficients f x) (list math-expr)+      {[<cons $a_0 <cons $a_1 <cons $a_2 <nil>>>>+        (q-f' a_2 a_1 a_0)]})))++(define $q-f'+  (lambda [$a $b $c]+    [(/ (+ (* -1 b) (sqrt (- (** b 2) (* 4 a c)))) (* 2 a))+     (/ (- (* -1 b) (sqrt (- (** b 2) (* 4 a c)))) (* 2 a))]))++;;;+;;; Cubic Equations+;;;+(define $cubic-formula c-f)++(define $c-f+  (lambda [$f $x]+    (match (coefficients f x) (list math-expr)+      {[<cons $a_0 <cons $a_1 <cons $a_2 <cons $a_3 <nil>>>>>+        (c-f' a_3 a_2 a_1 a_0)]})))++(define $c-f'+  (lambda [$a $b $c $d]+    (match [a b c d] [math-expr math-expr math-expr math-expr]+      {[[,1 ,0 $p $q]+        (let {[[$u3 $v3] (q-f' 1 q (/ (* -1 p^3) 27))]}+          [(+ (rt 3 u3) (rt 3 v3))+           (+ (* w (rt 3 u3)) (* w^2 (rt 3 v3)))+           (+ (* w^2 (rt 3 u3)) (* w (rt 3 v3)))]+          )]+       [[,1 $a2 $a1 $a0]+        (let {[[$y1 $y2 $y3] (c-f' 1 0 (- a1 (/ a2^2 3)) (+ a0 (* (/ -1 3) a1 a2) (* (/ 2 27) a2^3)))]}+          [(- y1 (/ a2 3)) (- y2 (/ a2 3)) (- y3 (/ a2 3))]+          )]+       [[_ _ _ _] (c-f' 1 (/ b a) (/ c a) (/ d a))]})))
+ lib/math/algebra/inverse.egi view
@@ -0,0 +1,44 @@+;;;;;+;;;;; Inverse+;;;;;++; (inverse t (* a x^2) x)+; t = (* a x^2)+; x = (sqrt (/ t a))++(define $inverse+  (lambda [$t $f $x]+    (match f math-expr+      {[?simple-term?+        (match f symbol-expr+          {[,x t]+           [(,exp ,x) (log t)]+           [(,log ,x) (exp t)]+           [(,sqrt ,x) (** t 2)]+           [(,cos ,x) (acos t)]+           [(,sin ,x) (asin t)]+           [(,acos ,x) (cos t)]+           [(,asin ,x) (sin t)]+           [_ (inverse' t f x)]+           })]+       [?term?+        (match f term-expr+          {[<term ,1 <ncons $n ,x <nil>>> (rt n t)]+           [<term _ <ncons $n ,x _>>+            (let {[$a (/ f (** x n))]}+              (inverse (/ t a) (/ f a) x))]+           [_ (inverse' t f x)]})]+       [?polynomial?+        (match (coefficients f x) (list math-expr)+          {[<cons $c (loop $i [1 $n] <cons ,0 ...> <cons $a <nil>>)>+            (inverse (/ (- t c) a) (** x (+ n 1)) x)]+           [_ (inverse' t f x)]})]+       [_+        (match f math-expr+          {[<div $p1 $p2>+            (inverse (* p2 t) p1 x)]})]+       [_ (inverse' t f x)]})))++(define $inverse'+  (lambda [$t $f $x]+    (to-math-expr <Apply inverse (map from-math-expr {t f x})>)))
+ lib/math/algebra/root.egi view
@@ -0,0 +1,80 @@+;;;;;+;;;;;+;;;;; Algebra+;;;;;+;;;;;++;;;+;;; Root+;;;++(define $rt+  (lambda [$n $x]+    (if (integer? n)+      (match x math-expr+        {[,0 0]+         [?monomial? (rt' n x)]+         [<div <plus $xs> <plus $ys>>+          (let {[$xd (reduce gcd xs)]+                [$yd (reduce gcd ys)]}+            (let {[[$a $r] (from-monomial (rt' n (/ xd yd)))]}+              (*' a+                 (rt'' n (*' (** r n) (/' (sum' (map (/' $ xd) xs)) (sum' (map (/' $ yd) ys)))))+                 )))]})+      (rt'' n x))))++(define $rt'+  (lambda [$n $x]+    (letrec {[$f (lambda [$xs]+                   (match xs (assoc-multiset integer)+                     {[<nil> [1 1]]+                      [<ncons $k $p $rs>+                       (let {[$ret (f rs)]}+                         [(*' (**' p (quotient k n)) (2#%1 ret)) (*' (**' p (remainder k n)) (2#%2 ret))])]}))]}+      (letrec {[$g (lambda [$x]+                     (match x term-expr+                       {[<term $a $xs>+                         (match (f {@(to-assoc (p-f (abs a))) @xs}) [math-expr math-expr]+                           {[[$x ,1] (if (lt? a 0) (*' (rtm1 n) x) x)]+                            [[$y $z] (if (lt? a 0) (*' (rtm1 n) y (rt'' n z)) (*' y (rt'' n z)))]})]}))]}+        (/' (g (numerator x)) (g (denominator x)))))))++(define $rt''+  (lambda [$n $x]+    (match [n x] [integer integer]+      {[[,2 _] (to-math-expr' <Apply sqrt (map from-math-expr {x})>)]+       [[_ _] (to-math-expr' <Apply rt (map from-math-expr {n x})>)]})))++(define $rtm1+  (lambda [$n]+    (match n integer+      {[,1 -1]+       [,2 i]+       [?odd? -1]+       [_ undefined]})))++(define $sqrt+  (lambda [$x]+    (if (number? x)+      (let {[$m (numerator x)]+            [$n (denominator x)]}+        (/ (rt 2 (* m n)) n))+      (b.sqrt x))))++(define $rt-of-unity rtu)++(define $rtu+  (lambda [$n]+    (rtu' n)))++(define $rtu'+  (lambda [$n]+    (if (integer? n)+      (match n integer+        {[,1 1]+         [,2 -1]+         [,3 w]+         [,4 i]+         [_ (to-math-expr' <Apply rtu (map from-math-expr {n})>)]+         })+      (to-math-expr' <Apply rtu (map from-math-expr {n})>))))
+ lib/math/algebra/tensor.egi view
@@ -0,0 +1,163 @@+;;;;;+;;;;;+;;;;; Tensor+;;;;;+;;;;;++(define $T.map+  (lambda [$fn $t]+    (tensor-map fn t)))++(define $T.map2+  (lambda [$fn $t1 $t2]+    (tensor-map2 fn t1 t2)))++(define $clear-index+  (lambda [$t]+    (| (tensor-size t)+       (tensor-to-list t) |)))++(define $unit-tensor+  (lambda [$ns]+    (generate-tensor kronecker-delta ns)))++(define $scalar-to-tensor+  (lambda [$x $ns]+    (T.map (* x $) (unit-tensor ns))))++(define $zero-tensor+  (lambda [$ns]+    (generate-tensor (cambda $ns 0) ns)))++(define $T.unit (unit-tensor $))+(define $T.zero (zero-tensor $))++;;+;; Arithmetic+;;+(define $T.arith+  (lambda [$op]+    (lambda [$t1 $t2]+      (match [(tensor? t1) (tensor? t2)] [bool bool]+        {[[,#t ,#t] (T.map2 op t1 t2)]+         [[,#t ,#f] (T.map2 op t1 (scalar-to-tensor t2 (tensor-size t1)))]+         [[,#f ,#t] (T.map2 op (scalar-to-tensor t1 (tensor-size t2)) t2)]+         }))))++(define $T.+ (T.arith +))+(define $T.- (T.arith -))++;;+;; Vectors+;;+(define $V.*+  (lambda [$v1 $v2]+    (. v1_i v2_i)))++;;+;; Matrices+;;+(define $M.*+  (cambda $ms+    (foldl M.*' (car ms) (cdr ms))))++(define $M.*'+  (lambda [$m1 $m2]+    (clear-index (. m1_i_j m2_j_k))))++(define $M.inverse+  (lambda [$m]+    (match (tensor-size m) (list integer)+      {[<cons ,2 <cons ,2 <nil>>>+        (T.map (/ $ (M.det m)) (| {2 2} {m_2_2 (* -1 m_1_2) (* -1 m_2_1) m_1_1} |))]+       [_ undefined]})))++;;+;; Linear algebra+;;+(define $M.LU+  (lambda [$x]+    (match (tensor-size x) (list integer)+      {[<cons ,2 <cons ,2 <nil>>>+        (let* {[$L (generate-tensor 2#(match (compare %1 %2) ordering {[<less> 0] [<equal> 1] [<greater> b_%1_%2]}) {2 2})]+               [$U (generate-tensor 2#(match (compare %1 %2) ordering {[<greater> 0] [_ c_%1_%2]}) {2 2})]+               [$m (M.* L U)]+               [$ret (solve {[m_1_1 x_1_1 c_1_1] [m_1_2 x_1_2 c_1_2]+                             [m_2_1 x_2_1 b_2_1] [m_2_2 x_2_2 c_2_2]})]}+          [(substitute ret L) (substitute ret U)])]+       [<cons ,3 <cons ,3 <nil>>>+        (let* {[$L (generate-tensor 2#(match (compare %1 %2) ordering {[<less> 0] [<equal> 1] [<greater> b_%1_%2]}) {3 3})]+               [$U (generate-tensor 2#(match (compare %1 %2) ordering {[<greater> 0] [_ c_%1_%2]}) {3 3})]+               [$m (M.* L U)]+               [$ret (solve {[m_1_1 x_1_1 c_1_1] [m_1_2 x_1_2 c_1_2] [m_1_3 x_1_3 c_1_3]+                             [m_2_1 x_2_1 b_2_1] [m_2_2 x_2_2 c_2_2] [m_2_3 x_2_3 c_2_3]+                             [m_3_1 x_3_1 b_3_1] [m_3_2 x_3_2 b_3_2] [m_3_3 x_3_3 c_3_3]})]}+          [(substitute ret L) (substitute ret U)])]+       [_ undefined]})))++;;+;; Determinant+;;+(define $even-and-odd-permutations+  (lambda [$n]+    (match n integer+      {[,2 [{{1 2}} {{2 1}}]]+       [_ (let* {[[$es $os] (even-and-odd-permutations (- n 1))]+                 [$es' (map 1#{@%1 n} es)]+                 [$os' (map 1#{@%1 n} os)]}+            [{@es'+              @(concat (map (lambda [$i] (map (permutate i n $) os')) (between 1 (- n 1))))+              }+             {@os'+              @(concat (map (lambda [$i] (map (permutate i n $) es')) (between 1 (- n 1))))+              }+             ]+            )]})))++(define $permutate+  (lambda [$x $y $xs]+    (match xs (list eq)+      {[<join $hs <cons ,x <join $ms <cons ,y $ts>>>>+        {@hs y @ms x @ts}]+       [<join $hs <cons ,y <join $ms <cons ,x $ts>>>>+        {@hs x @ms y @ts}]})))++(define $M.determinant+  (lambda [$m]+    (match (tensor-size m) (list integer)+      {[<cons $n <cons ,n <nil>>>+        (let {[[$es $os] (even-and-odd-permutations n)]}+          (- (sum (map (lambda [$e]+                         (product (map2 (lambda [$i $j] m_i_j)+                                        (between 1 n)+                                        e)))+                       es))+             (sum (map (lambda [$o]+                         (product (map2 (lambda [$i $j] m_i_j)+                                        (between 1 n)+                                        o)))+                       os))))]+       [_ undefined]})))++(define $M.det M.determinant)++;;;+;;; Eigenvalue+;;;+(define $M.eigenvalues+  (lambda [$m]+    (match (tensor-size m) (list integer)+      {[<cons ,2 <cons ,2 <nil>>>+        (let {[[$e1 $e2] (q-f (M.det (T.- m (scalar-to-tensor x {2 2}))) x)]}+          {e1 e2})]+       [_ undefined]})))++(define $M.eigenvectors+  (lambda [$m]+    (match (tensor-size m) (list integer)+      {[<cons ,2 <cons ,2 <nil>>>+        (let {[[$e1 $e2] (q-f (M.det (T.- m (scalar-to-tensor x {2 2}))) x)]}+          {[e1 (clear-index (T.- m (scalar-to-tensor e1 {2 2}))_i_1)]+           [e2 (clear-index (T.- m (scalar-to-tensor e2 {2 2}))_i_1)]})+        ]+       [_ undefined]})))
+ lib/math/analysis/derivative.egi view
@@ -0,0 +1,55 @@+;;;;;+;;;;;+;;;;; Differentiation+;;;;;+;;;;;++(define $d/d+  (lambda [$f $x]+    (match f math-expr+      {[?simple-term?+        (match [x f] [symbol-expr symbol-expr]+          {[[<symbol $name> <symbol !,name>] 0]+           [[<symbol $name> <symbol ,name>] 1]+           [[_ (,exp $g)] (* (exp g) (d/d g x))]+           [[_ (,** $g $h)] (* f (d/d (* (log g) h) x))]+           [[_ (,log $g)] (* (/ 1 g) (d/d g x))]+           [[_ (,cos $g)] (* (* -1 (sin g)) (d/d g x))]+           [[_ (,sin $g)] (* (cos g) (d/d g x))]+           [[_ (,sqrt $g)] (* (/ 1 (* 2 (sqrt g))) (d/d g x))]+           })]+       [?term?+        (match f term-expr+          {[<term _ <nil>> 0]+           [<term ,1 <ncons $n $fx <nil>>> (* n (** fx (- n 1)) (d/d fx x))]+           [<term $a <ncons $n $fx $ts>>+            (+ (* a+                  (d/d (** fx n) x)+                  (foldl *' 1 (map 2#(**' %1 %2) ts)))+               (* a+                  (** fx n)+                  (d/d (foldl *' 1 (map 2#(**' %1 %2) ts)) x)))]+           })]+       [?polynomial?+        (match f poly-expr+          {[<plus $ts> (sum (map (d/d $ x) ts))]})]+       [_+        (match f math-expr+          {[<div $p1 $p2>+            (let {[$p1' (d/d p1 x)]+                  [$p2' (d/d p2 x)]}+              (/ (- (* p1' p2) (* p2' p1)) (** p2 2)))]+           })]+       })))++(define $d/dx (d/d $ x)) ; just a syntax sugar+(define $d/dy (d/d $ y)) ; just a syntax sugar+(define $d/dz (d/d $ z)) ; just a syntax sugar++(define $taylor-expansion+  (lambda [$f $x $a]+    (map2 *+          (map 1#(/ (** (- x a) %1) (fact %1)) nats0)+          (map (substitute {[x a]} $) (iterate (d/d $ x) f)))))++(define $maclaurin-expansion (taylor-expansion $ $ 0))
+ lib/math/analysis/integral.egi view
@@ -0,0 +1,61 @@+;;;;;+;;;;;+;;;;; Integration+;;;;;+;;;;;++(define $Sd+  (lambda [$x $f]+    (match f math-expr+      {[?simple-term?+        (match [x f] [symbol-expr symbol-expr]+          {[[<symbol $name> <symbol !,name>] (* f x)]+           [[<symbol $name> <symbol ,name>] (* (/ 1 2) x^2)]+           [[_ (,exp ,x)] (exp x)]+           [[_ (,cos ,x)] (sin x)]+           [[_ (,sin ,x)] (* -1 (cos x))]+           [[_ (,log ,x)] (multSd x 1 (log x))]+           [[_ ($f $y)] (substitute {[tmpvar y]} (Sd tmpvar (* (f tmpvar) (d/d (inverse tmpvar y x) tmpvar))))]+           [[_ (,** $a ,x)] (/ (** a x) (log a))]+           [[_ (,** $a $y)] (substitute {[tmpvar y]} (Sd tmpvar (* (** a tmpvar) (d/d (inverse tmpvar y x) tmpvar))))]+           [[_ _] (Sd' x f)]+           })]+       [?term?+        (match f term-expr+          {[<term $a <ncons $n ,x $ts>>+            (let {[$b (foldl *' a (map 2#(**' %1 %2) ts))]}+              (if (contain-symbol? x b)+                (Sd' x f)+                (/ (* b (** x (+ n 1))) (+ n 1))))]+           [<term $a $ts>+            (let {[[$fxs $cs] (partition (contain-symbol? x $) (from-assoc ts))]}+              (match fxs (list math-expr)+                {[<nil> (* f x)]+                 [<cons $fx <nil>> (* a (Sd x fx) (foldl *' 1 cs))]+                 [_ (Sd' x f)]}))]})]+       [?polynomial?+        (match f poly-expr+          {[<plus $ts> (sum (map (Sd x $) ts))]})]+       [_+        (match f math-expr+          {[<div $p1 $p2>+            (match (coefficients p2 x) (list math-expr)+              {[<cons $a <nil>> (/ (Sd x p1) a)]+               [_ (Sd' x f)]})]})]+       })))++(define $multSd+  (lambda [$x $f $g]+    (let {[$F (Sd x f)]}+      (- (* F g)+         (Sd x (* F (d/d g x)))))))++(define $Sd'+  (lambda [$x $f]+    (to-math-expr <Apply Sd (map from-math-expr {x f})>)))++(define $dSd+  (lambda [$x $a $b $f]+    (let {[$F (Sd x f)]}+      (- (substitute {[x b]} F)+         (substitute {[x a]} F)))))
+ lib/math/common/arithmetic.egi view
@@ -0,0 +1,93 @@+;;;;;+;;;;;+;;;;; Arithmetic Operation+;;;;;+;;;;;++(define $to-math-expr (macro [$arg] (math-normalize (apply to-math-expr' arg))))++(define $+' (cambda $xs (foldl b.+' (car xs) (cdr xs))))+(define $-' (cambda $xs (foldl b.-' (car xs) (cdr xs))))+(define $*' (cambda $xs (foldl b.*' (car xs) (cdr xs))))+(define $/' b./')+(define $.' (cambda $xs (foldl b..' (car xs) (cdr xs))))++(define $b.+ (macro [$x1 $x2] (math-normalize (b.+' x1 x2))))+(define $b.- (macro [$x1 $x2] (math-normalize (b.-' x1 x2))))+(define $b.* (macro [$x1 $x2] (math-normalize (b.*' x1 x2))))+(define $b./ (macro [$x1 $x2] (math-normalize (b./' x1 x2))))+(define $b.. (macro [$x1 $x2] (math-normalize (b..' x1 x2))))++(define $+ (cambda $xs (foldl b.+ (car xs) (cdr xs))))+(define $- (cambda $xs (foldl b.- (car xs) (cdr xs))))+(define $* (cambda $xs (foldl b.* (car xs) (cdr xs))))+(define $/ b./)+(define $. (cambda $xs (foldl b.. (car xs) (cdr xs))))++(define $sum+  (lambda [$xs]+    (foldl + 0 xs)))++(define $sum'+  (lambda [$xs]+    (foldl +' 0 xs)))++(define $product+  (lambda [$xs]+    (foldl * 1 xs)))++(define $product'+  (lambda [$xs]+    (foldl *' 1 xs)))++(define $power+  (lambda [$x $n]+    (foldl * 1 (take n (repeat1 x)))))++(define $power'+  (lambda [$x $n]+    (foldl *' 1 (take n (repeat1 x)))))++(define $**+  (lambda [$x $n]+    (if (eq? x e)+      (exp n)+      (if (rational? n)+        (if (gte? n 0)+          (if (integer? n)+            (power x n)+            (to-math-expr <Apply ** (map from-math-expr {x n})>))+          (/ 1 (** x (neg n))))+        (to-math-expr <Apply ** (map from-math-expr {x n})>)))))++(define $**'+  (lambda [$x $n]+    (if (rational? n)+      (if (gte? n 0)+        (if (integer? n)+          (power' x n)+          (to-math-expr' <Apply ** (map from-math-expr {x n})>))+        (/' 1 (**' x (neg n))))+      (to-math-expr' <Apply ** (map from-math-expr {x n})>))))++(define $gcd+  (cambda $xs+    (foldl b.gcd (car xs) (cdr xs))))++(define $gcd'+  (cambda $xs+    (foldl b.gcd' (car xs) (cdr xs))))++(define $b.gcd+  (lambda [$x $y]+    (match [x y] [term-expr term-expr]+      {[[<term $a $xs> <term $b $ys>]+        (* (b.gcd' (abs a) (abs b)) (foldl *' 1 (map 2#(**' %1 %2) (AC.intersect xs ys))))]})))++(define $b.gcd'+  (lambda [$x $y]+    (match [x y] [integer integer]+      {[[,0 _] y]+       [[_ ,0] x]+       [[_ ?(gte? $ x)] (b.gcd' (modulo y x) x)]+       [[_ _] (b.gcd' y x)]})))
+ lib/math/common/functions.egi view
@@ -0,0 +1,96 @@+;;;;;+;;;;;+;;;;; Mathematical Functions+;;;;;+;;;;;++(define $exp+  (lambda [$x]+    (if (float? x)+      (b.exp x)+      (if (term? x)+        (match x term-expr+          {[,0 1]+           [,1 e]+           [<term $a <cons ,i <cons ,pi <nil>>>> (** -1 a)]+           [_ (to-math-expr <Apply exp (map from-math-expr {x})>)]})+        (to-math-expr <Apply exp (map from-math-expr {x})>)))))++(define $log+  (lambda [$x]+    (if (float? x)+      (b.log x)+      (match x math-expr+        {[,1 0]+         [,e 1]+         [_ (to-math-expr <Apply log (map from-math-expr {x})>)]}))))++(define $cos+  (lambda [$x]+    (if (float? x)+      (b.cos x)+      (match x math-expr+        {[,0 1]+         [,(* 2 pi) 1]+         [_ (to-math-expr <Apply cos (map from-math-expr {x})>)]}))))++(define $sin+  (lambda [$x]+    (if (float? x)+      (b.sin x)+      (match x math-expr+        {[,0 0]+         [_ (to-math-expr <Apply sin (map from-math-expr {x})>)]}))))++(define $tan+  (lambda [$x]+    (if (float? x)+      (b.tan x)+      (match x math-expr+        {[,0 0]+         [_ (to-math-expr <Apply tan (map from-math-expr {x})>)]}))))++(define $cosh+  (lambda [$x]+    (if (float? x)+      (b.cosh x)+      (match x math-expr+        {[,0 1]+         [_ (to-math-expr <Apply cosh (map from-math-expr {x})>)]}))))++(define $sinh+  (lambda [$x]+    (if (float? x)+      (b.sinh x)+      (match x math-expr+        {[,0 0]+         [_ (to-math-expr <Apply sinh (map from-math-expr {x})>)]}))))++(define $tanh+  (lambda [$x]+    (if (float? x)+      (b.tanh x)+      (match x math-expr+        {[,0 0]+         [_ (to-math-expr <Apply tanh (map from-math-expr {x})>)]}))))+++(define $sinc+  (lambda [$x]+    (if (float? x)+      (if (eq? x 0.0)+        1.0+        (/ (b.sin x) x))+      (match x math-expr+        {[,0 1]+         [_ (/ (sin x) x)]}))))+++(define $sigmoid+  (lambda [$z]+    (/ 1 (+ 1 (exp (* -1 z))))))+++(define $kronecker-delta+  (cambda $js+    (if (all (eq? $ (car js)) (cdr js)) 1 0)))
+ lib/math/expression.egi view
@@ -0,0 +1,242 @@+;;;;;+;;;;;+;;;;; Mathematics Expressions+;;;;;+;;;;;++(define $math-expr+  (matcher+    {[,$val []+      {[$tgt (if (eq? val tgt)+               {[]}+               {})]}]+     [$ [math-expr']+      {[<Div $p1 $p2> {<Div p1 p2>}]+       [$tgt {(from-math-expr tgt)}]}]+     }))++(define $math-expr'+  (matcher+    {[<div $ $> [poly-expr poly-expr]+      {[<Div $p1 $p2> {[(to-math-expr' p1) (to-math-expr' p2)]}]+       [_ {}]}]+     [$ [something]+      {[$tgt {(to-math-expr' tgt)}]}]+     }))++(define $poly-expr+  (matcher+    {[,$val []+      {[$tgt (if (eq? val tgt)+               {[]}+               {})]}]+     [$ [poly-expr']+      {[<Plus $ts> {<Plus ts>}]+       [<Div <Plus $ts> <Plus {<Term 1 {}> @{}}>> {<Plus ts>}]+       [$tgt {(from-math-expr tgt)}]}]+     }))++(define $poly-expr'+  (matcher+    {[<plus $> [(multiset term-expr)]+      {[<Plus $ts> {(map to-math-expr' ts)}]+       [<Div <Plus $ts> <Plus {<Term 1 {}> @{}}>> {(map to-math-expr' ts)}]+       [_ {}]}]+     [$ [something]+      {[$tgt {(to-math-expr' tgt)}]}]+     }))++(define $term-expr+  (matcher+    {[,$val []+      {[$tgt (if (eq? val tgt)+               {[]}+               {})]}]+     [<mult ,$val $> [term-expr]+      {[$tgt (if (term? (/ tgt val))+               {(/ tgt val)}+               {})]}]+     [$ [term-expr']+      {[<Term $n $xs> {<Term n xs>}]+       [<Div <Plus {<Term $n $xs> @{}}> <Plus {<Term 1 {}> @{}}>> {<Term n xs>}]+       [$tgt {(from-math-expr tgt)}]}]+     }))++(define $term-expr'+  (matcher+    {[<term $ $> [integer (assoc-multiset symbol-expr)]+      {[<Term $n $xs> {[n (map 2#[(to-math-expr' %1) %2] xs)]}]+       [<Div <Plus {<Term $n $xs> @{}}> <Plus {<Term 1 {}> @{}}>> {[n (map 2#[(to-math-expr' %1) %2] xs)]}]+       [_ {}]}]+     [$ [something]+      {[$tgt {(to-math-expr' tgt)}]}]+     }))++(define $symbol-expr+  (matcher+    {[,$val []+      {[$tgt (if (eq? val tgt)+                 {[]}+                 {})]}]+     [$ [symbol-expr']+      {[<Symbol $v> {<Symbol v>}]+       [<Div <Plus {<Term 1 {[<Symbol $v> 1] @{}}> @{}}> <Plus {<Term 1 {}> @{}}>> {<Symbol v>}]+       [<Apply $v $mexprs> {<Apply v mexprs>}]+       [<Div <Plus {<Term 1 {[<Apply $v $mexprs> 1] @{}}> @{}}> <Plus {<Term 1 {}> @{}}>> {<Apply v mexprs>}]+       [$tgt {(from-math-expr tgt)}]}]+     }))++(define $symbol-expr'+  (matcher+    {[<symbol $> [string]+      {[<Symbol $v> {v}]+       [<Div <Plus {<Term 1 {[<Symbol $v> 1] @{}}> @{}}> <Plus {<Term 1 {}> @{}}>> {v}]+       [_ {}]}]+     [<apply $ $> [eq (list math-expr)]+      {[<Apply $v $mexprs> [v mexprs]]+       [<Div <Plus {<Term 1 {[<Apply $v $mexprs> 1] @{}}> @{}}>+             <Plus {<Term 1 {}> @{}}>> {[v (map to-math-expr' mexprs)]}]+       [_ {}]}]+     [$ [something]+      {[$tgt {(to-math-expr' tgt)}]}]+     }))++(define $symbol?+  (lambda [$mexpr]+    (match mexpr math-expr+      {[<div <plus <cons <term ,1 <cons <symbol _> <nil>>> <nil>>>+             <plus <cons <term ,1 <nil>> <nil>>>>+        #t]+       [_ #f]})))++(define $simple-term?+  (lambda [$mexpr]+    (match mexpr math-expr+      {[<div <plus <cons <term ,1 <cons _ <nil>>> <nil>>>+             <plus <cons <term ,1 <nil>> <nil>>>>+        #t]+       [,0 #t]+       [_ #f]})))++(define $term?+  (lambda [$mexpr]+    (match mexpr math-expr+      {[<div <plus <cons _ <nil>>>+             <plus <cons <term ,1 <nil>> <nil>>>>+        #t]+       [,0 #t]+       [_ #f]})))++(define $polynomial?+  (lambda [$mexpr]+    (match mexpr math-expr+      {[<div _+             <plus <cons <term ,1 <nil>> <nil>>>>+        #t]+       [,0 #t]+       [_ #f]})))++(define $monomial?+  (lambda [$mexpr]+    (match mexpr math-expr+      {[<div <plus <cons <term _ _> <nil>>>+             <plus <cons <term _ _> <nil>>>>+        #t]+       [,0 #t]+       [_ #f]})))++(define $from-monomial+  (lambda [$mexpr]+    (match mexpr math-expr+      {[<div <plus <cons <term $a $xs> <nil>>>+             <plus <cons <term $b $ys> <nil>>>>+        [(/ a b)+         (/ (foldl *' 1 (map 2#(**' %1 %2) xs))+            (foldl *' 1 (map 2#(**' %1 %2) ys)))]]})))++;;+;; Map+;;+(define $map-terms+  (lambda [$fn $mexpr]+    (match mexpr math-expr+      {[<div <plus $ts1> <plus $ts2>>+        (/' (foldl +' 0 (map fn ts1))+            (foldl +' 0 (map fn ts2)))]})))++(define $map-symbols+  (lambda [$fn $mexpr]+    (map-terms (lambda [$term]+                 (match term term-expr+                   {[<term $a $xs>+                     (*' a (foldl *' 1 (map 2#(match %1 symbol-expr+                                                {[<symbol _> (**' (fn %1) %2)]+                                                 [<apply $g $args>+                                                  (** (fn (capply g (map (map-symbols fn $) args)))+                                                      %2)+                                                  ]})+                                            xs)))]}))+               mexpr)))++(define $contain-symbol?+  (lambda [$x $mexpr]+    (any id (match mexpr math-expr+              {[<div <plus $ts1> <plus $ts2>>+                (map (lambda [$term]+                       (match term term-expr+                         {[<term _ $xs>+                           (any id (map 2#(match %1 symbol-expr+                                            {[,x #t]+                                             [<apply _ $args> (any id (map (contain-symbol? x $) args))]+                                             [_ #f]})+                                        xs))]}))+                     {@ts1 @ts2})]}))))++;;;+;;; Substitute+;;;+(define $substitute+  (lambda [$ls $mexpr]+    (if (tensor? mexpr)+      (tensor-map (substitute ls $) mexpr)+      (match ls (list [symbol-expr math-expr])+        {[<nil> mexpr]+         [<cons [$x $a] $rs>+          (substitute rs (substitute' x a mexpr))]}))))++(define $substitute'+  (lambda [$x $a $mexpr]+    (map-symbols (rewrite-symbol x a $) mexpr)))++(define $rewrite-symbol +  (lambda [$x $a $sexpr]+    (match sexpr symbol-expr+      {[,x a]+       [_ sexpr]})))++;;;+;;; Coefficient+;;;+(define $coefficients+  (lambda [$f $x]+    (let {[$m (capply max {0 @(match-all f math-expr+                                [<div <plus <cons <term $a <ncons $k ,x $ts>> _>> _> k])})]}+      (map (coefficient f x $) (between 0 m)))))++(define $coefficient+  (lambda [$f $x $m]+    (if (eq? m 0)+      (/ (sum (match-all f math-expr+                [<div <plus <cons <term $a (& !<cons ,x _> $ts)> _>> _>+                 (foldl *' a (map 2#(**' %1 %2) ts))]))+         (denominator f))+      (coefficient' f x m))))++(define $coefficient'+  (lambda [$f $x $m]+    (/ (sum (match-all f math-expr+              [<div <plus <cons <term $a <ncons $k ,x $ts>> _>> _>+               (if (eq? m k)+                 (foldl *' a (map 2#(**' %1 %2) ts))+                 0)]))+       (denominator f))))
+ lib/math/normalize.egi view
@@ -0,0 +1,74 @@+;;;;;+;;;;;+;;;;; Term Rewriting+;;;;;+;;;;;++;(set-term-rewriting-rule {[(rt $n $x)^,n x]+;                          [(* (sqrt $x) (sqrt $y)) (* (gcd x y) (sqrt (/ (* x y) (gcd x y))))]+;                          [(rtu $n)^,n 1]+;                          [w^3 1]+;                          [w^2 (- -1 w)]+;                          [i^2 -1]})++(define $math-normalize+  (lambda [$mexpr]+    (if (tensor? mexpr)+      (tensor-map math-normalize mexpr)+      (if (number? mexpr)+        (if (rational? mexpr)+          mexpr+          (map-terms rewrite-rule-rt+                     (map-terms rewrite-rule-sqrt+                                (map-terms rewrite-rule-rtu+                                           (map-terms rewrite-rule-w+                                                      (map-terms rewrite-rule-i+                                                                 mexpr+                                                                 ))))))+        mexpr))))++(define $rewrite-rule-i+  (lambda [$term]+    (match term term-expr+      {[<term $a <ncons (& ?even? $k) ,i $ts>>+        (*' a (**' -1 (quotient k 2)) (foldl *' 1 (map 2#(**' %1 %2) ts)))]+       [<term $a <ncons $k ,i $ts>>+        (*' a (**' -1 (quotient k 2)) i (foldl *' 1 (map 2#(**' %1 %2) ts)))]+       [_ term]})))++(define $rewrite-rule-w+  (lambda [$term]+    (match term term-expr+      {[<term $a <ncons (& ?(gte? $ 3) $k) ,w $ts>>+        (*' a (**' w (remainder k 3)) (foldl *' 1 (map 2#(**' %1 %2) ts)))]+       [<term $a <ncons ,2 ,w $ts>>+        (*' a (- -1 w) (foldl *' 1 (map 2#(**' %1 %2) ts)))]+       [_ term]})))++(define $rewrite-rule-rtu+  (lambda [$term]+    (match term term-expr+      {[<term $a <ncons $k (,rtu (& ?(gte? k $) $n)) $ts>>+        (*' a (**' (rtu n) (remainder k n)) (foldl *' 1 (map 2#(**' %1 %2) ts)))]+       [_ term]})))++(define $rewrite-rule-sqrt+  (lambda [$term]+    (match term term-expr+      {[<term $a <cons (,sqrt $x) <cons (,sqrt ,x) $ts>>>+        (* a x (foldl *' 1 (map 2#(**' %1 %2) ts)))]+       [<term $a <cons (,sqrt (& ?term? $x)) <cons (,sqrt (& ?term? $y)) $ts>>>+        (let* {[$d (gcd x y)]+               [[$a1 $x1] (from-monomial (/ x d))]+               [[$a2 $y1] (from-monomial (/ y d))]}+            (*' a d+               (sqrt (*' a1 a2)) (sqrt x1) (sqrt y1)+               (foldl *' 1 (map 2#(**' %1 %2) ts))))]+       [_ term]})))++(define $rewrite-rule-rt+  (lambda [$term]+    (match term term-expr+      {[<term $a <ncons $k (,rt (& ?(gte? k $) $n) $x) $ts>>+        (*' a (**' x (quotient k n)) (**' (rt n x) (remainder k n)) (foldl *' 1 (map 2#(**' %1 %2) ts)))]+       [_ term]})))
sample/bipartite-graph.egi view
@@ -48,14 +48,14 @@                 (match-all bipartite-graph-data (bipartite-graph integer string)                   [<cons <edge $n $str>                          <cons <edge ,n ,str>-                               ^<cons <edge ,n ^,str> _>>>+                               !<cons <edge ,n !,str> _>>>                    n])))  (test (unique/m integer                 (match-all bipartite-graph-data (bipartite-graph integer string)                   [<cons <edge $n $str>                          <cons <edge ,n ,str>-                               ^<cons <edge ,n ^,str> _>>>+                               !<cons <edge ,n !,str> _>>>                    n])))  (test (unique/m integer@@ -76,12 +76,12 @@ ;                  [(& <cons <edge $n $str> ;                            <cons <edge ,n ,str> ;                                  <cons <edge ,n ,str> _>>>-;                      ^<cons <edge $n2 $str2>-;                             ^<cons <edge ,n2 ,str2> _>>)+;                      !<cons <edge $n2 $str2>+;                             !<cons <edge ,n2 ,str2> _>>) ;                   n])))  (test (unique/m integer                 (match-all bipartite-graph-data (bipartite-graph integer string)                   [<cons <edge $n2 $str2>-                         ^<cons <edge ,n2 ,str2> _>>+                         !<cons <edge ,n2 ,str2> _>>                   n2])))
sample/graph.egi view
@@ -51,7 +51,7 @@ (test (let {[$s 1]}         (match-all graph-data1 (graph integer)           [<cons <edge ,s $x>-                 ^<cons <edge ,x ,s>+                 !<cons <edge ,x ,s>                         _>>            x]))) 
sample/n-queen.egi view
@@ -1,40 +1,40 @@ (define $eight-queen   (match-all {1 2 3 4 5 6 7 8} (multiset integer)     [<cons $a_1-      <cons (& ^,(- a_1 1) ^,(+ a_1 1)+      <cons (& !,(- a_1 1) !,(+ a_1 1)                $a_2)-       <cons (& ^,(- a_1 2) ^,(+ a_1 2)-                ^,(- a_2 1) ^,(+ a_2 1)+       <cons (& !,(- a_1 2) !,(+ a_1 2)+                !,(- a_2 1) !,(+ a_2 1)                 $a_3)-        <cons (& ^,(- a_1 3) ^,(+ a_1 3)-                 ^,(- a_2 2) ^,(+ a_2 2)-                 ^,(- a_3 1) ^,(+ a_3 1)+        <cons (& !,(- a_1 3) !,(+ a_1 3)+                 !,(- a_2 2) !,(+ a_2 2)+                 !,(- a_3 1) !,(+ a_3 1)                  $a_4)-          <cons (& ^,(- a_1 4) ^,(+ a_1 4)-                   ^,(- a_2 3) ^,(+ a_2 3)-                   ^,(- a_3 2) ^,(+ a_3 2)-                   ^,(- a_4 1) ^,(+ a_4 1)+          <cons (& !,(- a_1 4) !,(+ a_1 4)+                   !,(- a_2 3) !,(+ a_2 3)+                   !,(- a_3 2) !,(+ a_3 2)+                   !,(- a_4 1) !,(+ a_4 1)                    $a_5)-           <cons (& ^,(- a_1 5) ^,(+ a_1 5)-                    ^,(- a_2 4) ^,(+ a_2 4)-                    ^,(- a_3 3) ^,(+ a_3 3)-                    ^,(- a_4 2) ^,(+ a_4 2)-                    ^,(- a_5 1) ^,(+ a_5 1)+           <cons (& !,(- a_1 5) !,(+ a_1 5)+                    !,(- a_2 4) !,(+ a_2 4)+                    !,(- a_3 3) !,(+ a_3 3)+                    !,(- a_4 2) !,(+ a_4 2)+                    !,(- a_5 1) !,(+ a_5 1)                     $a_6)-            <cons (& ^,(- a_1 6) ^,(+ a_1 6)-                     ^,(- a_2 5) ^,(+ a_2 5)-                     ^,(- a_3 4) ^,(+ a_3 4)-                     ^,(- a_4 3) ^,(+ a_4 3)-                     ^,(- a_5 2) ^,(+ a_5 2)-                     ^,(- a_6 1) ^,(+ a_6 1)+            <cons (& !,(- a_1 6) !,(+ a_1 6)+                     !,(- a_2 5) !,(+ a_2 5)+                     !,(- a_3 4) !,(+ a_3 4)+                     !,(- a_4 3) !,(+ a_4 3)+                     !,(- a_5 2) !,(+ a_5 2)+                     !,(- a_6 1) !,(+ a_6 1)                      $a_7)-             <cons (& ^,(- a_1 7) ^,(+ a_1 7)-                      ^,(- a_2 6) ^,(+ a_2 6)-                      ^,(- a_3 5) ^,(+ a_3 5)-                      ^,(- a_4 4) ^,(+ a_4 4)-                      ^,(- a_5 3) ^,(+ a_5 3)-                      ^,(- a_6 2) ^,(+ a_6 2)-                      ^,(- a_7 1) ^,(+ a_7 1)+             <cons (& !,(- a_1 7) !,(+ a_1 7)+                      !,(- a_2 6) !,(+ a_2 6)+                      !,(- a_3 5) !,(+ a_3 5)+                      !,(- a_4 4) !,(+ a_4 4)+                      !,(- a_5 3) !,(+ a_5 3)+                      !,(- a_6 2) !,(+ a_6 2)+                      !,(- a_7 1) !,(+ a_7 1)                       $a_8)               <nil>>>>>>>>>      a]))@@ -47,8 +47,8 @@       [<cons $a_1              (loop $i [2 n]                    <cons (loop $i1 [1 (- i 1)]-                               (& ^,(- a_i1 (- i i1))-                                  ^,(+ a_i1 (- i i1))+                               (& !,(- a_i1 (- i i1))+                                  !,(+ a_i1 (- i i1))                                   ...)                                $a_i)                          ...>
sample/one-minute-first.egi view
@@ -2,7 +2,7 @@ (test (match-all {1 2 3 4 3 5 2 6} (multiset integer) [<cons $x <cons ,x _>> x]))  ; enumerate the elements of the collection that appear only once-(test (match-all {1 2 3 4 3 5 2 6} (multiset integer) [<cons $x ^<cons ,x _>> x]))+(test (match-all {1 2 3 4 3 5 2 6} (multiset integer) [<cons $x !<cons ,x _>> x]))  ; enumerate the elements of the collection if all of the three consecutive numbers from it are contained in the collection. (test (match-all {1 2 13 14 3 15 2 6} (multiset integer) [<cons $x <cons ,(+ x 1) <cons ,(+ x 2) _>>> x]))
sample/randomized-3sat.egi view
@@ -16,7 +16,7 @@      [[$p $n ,0 $r  _] (R.sat-solver p n (- r 1))]      [[$p $n $k $r $a]       (match (randomize p) (multiset (R.multiset [integer bool]))-        {[<cons (& ^?(clause-satisfy? $ a) <cons [$i _] _>) _>+        {[<cons (& !?(clause-satisfy? $ a) <cons [$i _] _>) _>           (random-walk-3sat p n (- k 1) r (A.update not i a))]          [_ <Just a>]})]})) 
sample/triangle.egi view
@@ -11,7 +11,7 @@ (match-all points (list [integer integer])   [<join _ <cons $p1     <join _ <cons $p2-     <join _ <cons (& ^?(on-a-line? p1 p2 $) $p3)+     <join _ <cons (& !?(on-a-line? p1 p2 $) $p3)        _>>>>>>    [p1 p2 p3]]) ;=>{[[3 1] [4 5] [7 7]] [[3 1] [4 5] [8 1]] [[3 1] [7 7] [8 1]] [[4 5] [7 7] [8 1]] [[3 1] [7 7] [1 9]] [[3 1] [8 1] [1 9]] [[4 5] [7 7] [1 9]] [[4 5] [8 1] [1 9]] [[7 7] [8 1] [1 9]] [[3 1] [4 5] [3 8]] [[3 1] [7 7] [3 8]] [[3 1] [8 1] [3 8]] [[3 1] [1 9] [3 8]] [[4 5] [7 7] [3 8]] [[4 5] [8 1] [3 8]] [[4 5] [1 9] [3 8]] [[7 7] [8 1] [3 8]] [[7 7] [1 9] [3 8]] [[8 1] [1 9] [3 8]] [[4 5] [7 7] [3 1]] [[4 5] [8 1] [3 1]] [[4 5] [1 9] [3 1]] [[4 5] [3 8] [3 1]] [[7 7] [8 1] [3 1]] [[7 7] [1 9] [3 1]] [[7 7] [3 8] [3 1]] [[8 1] [1 9] [3 1]] [[8 1] [3 8] [3 1]] [[1 9] [3 8] [3 1]]}