{-# LANGUAGE OverloadedStrings, TupleSections, FlexibleInstances #-} module Funcons.Types ( module Funcons.Types, module VAL,) where import qualified Funcons.Operations as VAL hiding (SortErr, ValueOp) import Funcons.Operations hiding (Name, Values, ComputationTypes, Types, isMap, isNull, isSet, map_empty_, isEnv, isDefinedVal, isChar, isVec, isType, isList, isNat, isInt, atoms_, integers_, values_, set_, list_, tuple_, atom_, nulltype_, non_null_values_, types_, value_types_, toList, isList, libFromList, listUnites, null) import qualified Data.Char as C import qualified Data.Map as M import qualified Data.Set as S import qualified Data.MultiSet as MS import qualified Data.Vector as V import Data.Maybe (isJust) import Data.Text (Text) import Data.Ratio type MetaVar = String type Name = Text -- | -- Internal representation of funcon terms. -- The generic constructors 'FName' and 'FApp' use names to represent -- nullary funcons and applications of funcons to other terms. -- Funcon terms are easily created using 'applyFuncon' or via -- the smart constructors exported by "Funcons.Core". data Funcons = FName Name | FApp Name [Funcons] -- | FTuple [Funcons] -- | FList [Funcons] | FSet [Funcons] | FMap [Funcons] | FBinding Funcons [Funcons] -- required for map-notation | FValue Values | FSortSeq Funcons VAL.SeqSortOp | FSortPower Funcons Funcons {- evals to natural number -} | FSortUnion Funcons Funcons | FSortInter Funcons Funcons | FSortComplement Funcons | FSortComputes Funcons | FSortComputesFrom Funcons Funcons deriving (Eq, Ord, Show, Read) -- | -- Build funcon terms by applying a funcon name to `zero or more' funcon terms. -- This function is useful for defining smart constructors, e,g, -- -- > handle_thrown_ :: [Funcons] -> Funcons -- > handle_thrown_ = applyFuncon "handle-thrown" -- -- or alternatively, -- -- > handle_thrown_ :: Funcons -> Funcons -> Funcons -- > handle_thrown_ x y = applyFuncon "handle-thrown" [x,y] applyFuncon :: Name -> [Funcons] -> Funcons applyFuncon str args | null args = FName str | otherwise = FApp str args tuple_ :: [Funcons] -> Funcons tuple_ = applyFuncon "tuple" -- | Creates a list of funcon terms. list_ :: [Funcons] -> Funcons list_ = applyFuncon "list" -- | Creates a set of funcon terms. set_ :: [Funcons] -> Funcons set_ = applyFuncon "set" -- | Funcon term representation identical to 'Funcons', -- but with meta-variables. data FTerm = TVar MetaVar | TName Name | TApp Name [FTerm] | TSeq [FTerm] -- a sequence of terms, consumed during substitution -- | TList [FTerm] | TSet [FTerm] | TMap [FTerm] | TBinding FTerm FTerm -- latter can be a sequence | TFuncon Funcons | TSortSeq FTerm VAL.SeqSortOp | TSortPower FTerm FTerm {- should eval to a natural number -} | TSortUnion FTerm FTerm | TSortInter FTerm FTerm | TSortComplement FTerm | TSortComputes FTerm | TSortComputesFrom FTerm FTerm | TAny -- used whenever funcon terms may have holes in them -- currently only the case in "downwards" flowing signals deriving (Eq, Ord, Show, Read) type Values = VAL.Values Funcons instance HasValues Funcons where inject = FValue project f = case f of FValue v -> Just v _ -> Nothing type Map = M.Map Values Values type Set = S.Set Values type Vectors = V.Vector Values -- | Representation of builtin types. type ComputationTypes = VAL.ComputationTypes Funcons type Types = VAL.Types Funcons type TTParam = (Types,Maybe VAL.SeqSortOp) binary32 :: Values binary32 = ADTVal "binary32" [] binary64 :: Values binary64 = ADTVal "binary64" [] adtval :: Name -> [Values] -> Values adtval nm = ADTVal nm . map FValue tuple_val__ :: [Values] -> Values tuple_val__ = adtval "tuple" tuple_val_ = FValue . tuple_val__ nullaryTypes :: [(Name,Types)] nullaryTypes = [ ("algebraic-datatypes", ADTs) , ("adts" , ADTs) -- , ("naturals", Naturals) -- , ("nats", Naturals) , ("rationals", Rationals) , ("values", VAL.Values) ] unaryTypes :: [(Name,Types->Types)] unaryTypes = [ ("multisets", multisets) -- , ("lists", Lists) -- , ("vectors", Vectors) ] binaryTypes :: [(Name,Types->Types->Types)] binaryTypes = [] boundedIntegerTypes :: [(Name, Integer -> Types)] boundedIntegerTypes = [] floatTypes :: [(Name, IEEEFormats -> Types)] floatTypes = [("ieee-floats", IEEEFloats)] --- smart constructors for values -- | Creates an integer 'literal'. int_ :: Int -> Funcons int_ = FValue . mk_integers . toInteger -- | Creates a natural 'literal'. nat_ :: Int -> Funcons nat_ i | i < 0 = int_ i | otherwise = FValue $ mk_naturals $ toInteger i bool_ :: Bool -> Funcons bool_ = FValue . bool__ bool__ :: Bool -> Values bool__ = VAL.tobool -- | Creates an atom from a 'String'. atom_ :: String -> Funcons atom_ = FValue . Atom -- | Creates a string literal. string_ :: String -> Funcons string_ = FValue . string__ string__ :: String -> Values string__ = ADTVal "list" . map char_ char_ :: Char -> Funcons char_ = FValue . char__ char__ :: Char -> Values char__ = mk_unicode_characters list__ :: [Values] -> Values list__ = VAL.list vector__ :: [Values] -> Values vector__ = VAL.vector tuple__ :: [Values] -> Values tuple__ = VAL.tuple float_ :: Double -> Funcons float_ = FValue . Float ieee_float_32_ :: Float -> Funcons ieee_float_32_ = FValue . IEEE_Float_32 ieee_float_64_ :: Double -> Funcons ieee_float_64_ = FValue . IEEE_Float_64 -- | The empty map as a 'Funcons'. empty_map_,map_empty_ :: Funcons empty_map_ = FValue (Map M.empty) map_empty_ = empty_map_ -- | The empty set as a 'Funcons'. empty_set_ :: Funcons empty_set_ = FValue (Set S.empty) -- | Creates a tuple of funcon terms. --tuple_ :: [Funcons] -> Funcons --tuple_ = FTuple type_ :: Types -> Funcons type_ = FValue . typeVal sort_ :: ComputationTypes -> Funcons sort_ = FValue . ComputationType comp_type_ :: ComputationTypes -> Funcons comp_type_ = FValue . ComputationType vec :: V.Vector (Values) -> Funcons vec = FValue . Vector vec_ :: [Values] -> Funcons vec_ = FValue . Vector . V.fromList -- idval :: Values -> Values -- idval = ID . ID' typeVal :: Types -> Values typeVal = ComputationType . Type fvalues :: [Values] -> [Funcons] fvalues = map FValue listval :: [Values] -> Funcons listval = FValue . ADTVal "list" . map FValue setval :: [Values] -> Funcons setval = FValue . setval_ setval_ :: [Values] -> Values setval_ = Set . S.fromList mapval :: [Values] -> Funcons mapval = FValue . mapval_ mapval_ :: [Values] -> Values mapval_ mvs = case mapM fromBinding mvs of Just vs -> Map $ M.fromListWith const vs _ -> error "mapval: invalid map-notation" fromBinding :: Values -> Maybe (Values, [Values]) fromBinding (ADTVal "tuple" (k':vs')) = do k <- project k' vs <- mapM project vs' return (k,vs) fromBinding k = Just (k,[]) -- subtyping rationals {- mk_rationals :: Rational -> Values mk_rationals r | denominator r == 1 = mk_integers (numerator r) | otherwise = Rational r mk_integers :: Integer -> Values mk_integers i | i >= 0 = mk_naturals i | otherwise = Int i mk_naturals :: Integer -> Values mk_naturals = Nat -} -- | Returns the /unicode/ representation of an assci value. -- Otherwise it returns the original value. --- Value specific -- | Attempt to downcast a funcon term to a value. downcastType :: Funcons -> Types downcastType (FValue v) = downcastValueType v downcastType _ = error "downcasting to sort failed" downcastSort :: Funcons -> ComputationTypes downcastSort (FValue (ComputationType s)) = s downcastSort _ = error "downcasting to sort failed" downcastValue :: Funcons -> Values downcastValue (FValue v) = v downcastValue _ = error "downcasting to value failed" recursiveFunconValue :: Funcons -> Maybe Values recursiveFunconValue (FValue v) = Just v --recursiveFunconValue (FList fs) = List <$> mapM recursiveFunconValue fs recursiveFunconValue (FSet fs) = Set . S.fromList <$> mapM recursiveFunconValue fs recursiveFunconValue (FMap fs) = do vs <- mapM recursiveFunconValue fs assocs <- mapM fromBinding vs return (Map $ M.fromList assocs) recursiveFunconValue _ = Nothing allEqual :: [Values] -> [Values] -> Bool allEqual xs ys = length xs == length ys && and (zipWith (===) xs ys) allUnEqual :: [Values] -> [Values] -> Bool allUnEqual xs ys = length xs /= length ys || or (zipWith (=/=) xs ys) isNull :: Funcons -> Bool isNull (FValue n) = n == null__ isNull _ = False hasStep (FValue _) = False hasStep _ = True isVal (FValue _) = True isVal _ = False isDefinedVal f = isVal f && not (isNull f) -- functions that check simple properties of funcons -- TODO: Some of these are used, and all are exported by Funcons.EDSL -- But are all of them still needed. E.g isId doesn't seem very useful now that ids are just strings. isString (FValue v) = isString_ v isString _ = False isChar (FValue v) = isJust (upcastCharacter v) isChar _ = False isNat (FValue (Int _)) = True isNat _ = False isInt (FValue (Int _)) = True isInt _ = False isList (FValue (ADTVal "list" _)) = True isList _ = False isEnv f = isMap f isMap (FValue (Map _)) = True isMap _ = False isSet (FValue (Set _)) = True isSet _ = False isTup _ = False isSort (FValue (ComputationType _)) = True isSort _ = False isSort_ (ComputationType _) = True isSort_ _ = False isType (FValue (ComputationType (Type _))) = True isType _ = False isVec (FValue (Vector _)) = True isVec _ = False isCharacter_ v = isJust (upcastCharacter v) integers_,values_ :: Funcons integers_ = type_ Integers values_ = type_ VAL.Values nulltype_ = type_ NullType vectors_ :: Types -> Funcons vectors_ = type_ . vectors -- type environment -- | The typing environment maps datatype names to their definitions. type TypeRelation = M.Map Name DataTypeMembers -- | A type parameter is of the form X:T where the name of the parameter,/X/, is optional. -- When present, /X/ can be used to specify the type of constructors. -- Variable /X/ be a sequence variable. type TypeParam = (Maybe MetaVar, Maybe VAL.SeqSortOp, FTerm) data TPattern = TPWildCard | TPVar MetaVar | TPSeqVar MetaVar VAL.SeqSortOp | TPLit FTerm {- should rewrite to a type -} | TPComputes TPattern | TPComputesFrom TPattern TPattern | TPADT Name [TPattern] deriving (Show, Eq, Ord, Read) -- | A datatype has `zero or more' type parameters and -- `zero or more' alternatives. data DataTypeMembers = DataTypeMemberss Name [TPattern] [DataTypeAltt] deriving (Show) -- | An alternative is either a datatype constructor or the inclusion -- of some other type. The types are arbitrary funcon terms (with possible -- variables) that may require evaluation to be resolved to a 'Types'. data DataTypeAltt = DataTypeInclusionn FTerm | DataTypeMemberConstructor Name [FTerm] (Maybe [TPattern]) deriving (Show) -- | Lookup the definition of a datatype in the typing environment. typeLookup :: Name -> TypeRelation -> Maybe DataTypeMembers typeLookup = M.lookup -- | The empty 'TypeRelation'. emptyTypeRelation :: TypeRelation emptyTypeRelation = M.empty -- | Unites a list of 'TypeRelation's. typeEnvUnions :: [TypeRelation] -> TypeRelation typeEnvUnions = foldr typeEnvUnion emptyTypeRelation -- | Unites two 'TypeRelation's. typeEnvUnion :: TypeRelation -> TypeRelation -> TypeRelation typeEnvUnion = M.unionWith (\_ _ -> error "duplicate type-name") -- | Creates a `TypeRelation' from a list. typeEnvFromList :: [(Name, DataTypeMembers)] -> TypeRelation typeEnvFromList = M.fromList