<commit_before>{-# LANGUAGE TypeFamilies, FlexibleContexts, FlexibleInstances, ConstraintKinds #-}
-- | This module provides various simple ways to query and manipulate
-- fundamental Futhark terms, such as types and values.  The intent is to
-- keep "Futhark.Reprsentation.AST.Syntax" simple, and put whatever
-- embellishments we need here.  This is an internal, desugared
-- representation.
module Futhark.Representation.AST.Attributes
  ( module Futhark.Representation.AST.Attributes.Reshape
  , module Futhark.Representation.AST.Attributes.Rearrange
  , module Futhark.Representation.AST.Attributes.Types
  , module Futhark.Representation.AST.Attributes.Values
  , module Futhark.Representation.AST.Attributes.Constants
  , module Futhark.Representation.AST.Attributes.TypeOf
  , module Futhark.Representation.AST.Attributes.Patterns
  , module Futhark.Representation.AST.Attributes.Names
  , module Futhark.Representation.AST.RetType

  -- * Built-in functions
  , isBuiltInFunction
  , builtInFunctions

  -- * Extra tools
  , funDefByName
  , asBasicOp
  , safeExp
  , subExpVars
  , subExpVar
  , shapeVars
  , commutativeLambda
  , entryPointSize
  , defAux
  , stmCerts
  , certify
  , expExtTypesFromPattern

  , IsOp (..)
  , Attributes (..)
  )
  where

import Data.List
import Data.Maybe (mapMaybe, isJust)
import Data.Monoid
import qualified Data.Map.Strict as M

import Futhark.Representation.AST.Attributes.Reshape
import Futhark.Representation.AST.Attributes.Rearrange
import Futhark.Representation.AST.Attributes.Types
import Futhark.Representation.AST.Attributes.Values
import Futhark.Representation.AST.Attributes.Constants
import Futhark.Representation.AST.Attributes.Patterns
import Futhark.Representation.AST.Attributes.Names
import Futhark.Representation.AST.Attributes.TypeOf
import Futhark.Representation.AST.RetType
import Futhark.Representation.AST.Syntax
import Futhark.Representation.AST.Pretty
import Futhark.Transform.Rename (Rename, Renameable)
import Futhark.Transform.Substitute (Substitute, Substitutable)
import Futhark.Util.Pretty

-- | @isBuiltInFunction k@ is 'True' if @k@ is an element of 'builtInFunctions'.
isBuiltInFunction :: Name -> Bool
isBuiltInFunction fnm = fnm `M.member` builtInFunctions

-- | A map of all built-in functions and their types.
builtInFunctions :: M.Map Name (PrimType,[PrimType])
builtInFunctions = M.fromList $ map namify $ M.toList primFuns
  where namify (k,(paramts,ret,_)) = (nameFromString k, (ret, paramts))

-- | Find the function of the given name in the Futhark program.
funDefByName :: Name -> Prog lore -> Maybe (FunDef lore)
funDefByName fname = find ((fname ==) . funDefName) . progFunctions

-- | If the expression is a 'BasicOp', return that 'BasicOp', otherwise 'Nothing'.
asBasicOp :: Exp lore -> Maybe (BasicOp lore)
asBasicOp (BasicOp op) = Just op
asBasicOp _           = Nothing

-- | An expression is safe if it is always well-defined (assuming that
-- any required certificates have been checked) in any context.  For
-- example, array indexing is not safe, as the index may be out of
-- bounds.  On the other hand, adding two numbers cannot fail.
safeExp :: IsOp (Op lore) => Exp lore -> Bool
safeExp (BasicOp op) = safeBasicOp op
  where safeBasicOp (BinOp SDiv{} _ (Constant y)) = not $ zeroIsh y
        safeBasicOp (BinOp SDiv{} _ _) = False
        safeBasicOp (BinOp UDiv{} _ (Constant y)) = not $ zeroIsh y
        safeBasicOp (BinOp UDiv{} _ _) = False
        safeBasicOp (BinOp SMod{} _ (Constant y)) = not $ zeroIsh y
        safeBasicOp (BinOp SMod{} _ _) = False
        safeBasicOp (BinOp UMod{} _ (Constant y)) = not $ zeroIsh y
        safeBasicOp (BinOp UMod{} _ _) = False
        safeBasicOp (BinOp Pow{} _ (Constant y)) = not $ negativeIsh y
        safeBasicOp (BinOp Pow{} _ _) = False
        safeBasicOp ArrayLit{} = True
        safeBasicOp BinOp{} = True
        safeBasicOp SubExp{} = True
        safeBasicOp UnOp{} = True
        safeBasicOp CmpOp{} = True
        safeBasicOp ConvOp{} = True
        safeBasicOp Scratch{} = True
        safeBasicOp Concat{} = True
        safeBasicOp Reshape{} = True
        safeBasicOp Manifest{} = True
        safeBasicOp _ = False

safeExp (DoLoop _ _ _ body) = safeBody body
safeExp (Apply fname _ _ _) = isBuiltInFunction fname
safeExp (If _ tbranch fbranch _) =
  all (safeExp . stmExp) (bodyStms tbranch) &&
  all (safeExp . stmExp) (bodyStms fbranch)
safeExp (Op op) = safeOp op<commit_msg>These division operations are also unsafe.<commit_after>{-# LANGUAGE TypeFamilies, FlexibleContexts, FlexibleInstances, ConstraintKinds #-}
-- | This module provides various simple ways to query and manipulate
-- fundamental Futhark terms, such as types and values.  The intent is to
-- keep "Futhark.Reprsentation.AST.Syntax" simple, and put whatever
-- embellishments we need here.  This is an internal, desugared
-- representation.
module Futhark.Representation.AST.Attributes
  ( module Futhark.Representation.AST.Attributes.Reshape
  , module Futhark.Representation.AST.Attributes.Rearrange
  , module Futhark.Representation.AST.Attributes.Types
  , module Futhark.Representation.AST.Attributes.Values
  , module Futhark.Representation.AST.Attributes.Constants
  , module Futhark.Representation.AST.Attributes.TypeOf
  , module Futhark.Representation.AST.Attributes.Patterns
  , module Futhark.Representation.AST.Attributes.Names
  , module Futhark.Representation.AST.RetType

  -- * Built-in functions
  , isBuiltInFunction
  , builtInFunctions

  -- * Extra tools
  , funDefByName
  , asBasicOp
  , safeExp
  , subExpVars
  , subExpVar
  , shapeVars
  , commutativeLambda
  , entryPointSize
  , defAux
  , stmCerts
  , certify
  , expExtTypesFromPattern

  , IsOp (..)
  , Attributes (..)
  )
  where

import Data.List
import Data.Maybe (mapMaybe, isJust)
import Data.Monoid
import qualified Data.Map.Strict as M

import Futhark.Representation.AST.Attributes.Reshape
import Futhark.Representation.AST.Attributes.Rearrange
import Futhark.Representation.AST.Attributes.Types
import Futhark.Representation.AST.Attributes.Values
import Futhark.Representation.AST.Attributes.Constants
import Futhark.Representation.AST.Attributes.Patterns
import Futhark.Representation.AST.Attributes.Names
import Futhark.Representation.AST.Attributes.TypeOf
import Futhark.Representation.AST.RetType
import Futhark.Representation.AST.Syntax
import Futhark.Representation.AST.Pretty
import Futhark.Transform.Rename (Rename, Renameable)
import Futhark.Transform.Substitute (Substitute, Substitutable)
import Futhark.Util.Pretty

-- | @isBuiltInFunction k@ is 'True' if @k@ is an element of 'builtInFunctions'.
isBuiltInFunction :: Name -> Bool
isBuiltInFunction fnm = fnm `M.member` builtInFunctions

-- | A map of all built-in functions and their types.
builtInFunctions :: M.Map Name (PrimType,[PrimType])
builtInFunctions = M.fromList $ map namify $ M.toList primFuns
  where namify (k,(paramts,ret,_)) = (nameFromString k, (ret, paramts))

-- | Find the function of the given name in the Futhark program.
funDefByName :: Name -> Prog lore -> Maybe (FunDef lore)
funDefByName fname = find ((fname ==) . funDefName) . progFunctions

-- | If the expression is a 'BasicOp', return that 'BasicOp', otherwise 'Nothing'.
asBasicOp :: Exp lore -> Maybe (BasicOp lore)
asBasicOp (BasicOp op) = Just op
asBasicOp _           = Nothing

-- | An expression is safe if it is always well-defined (assuming that
-- any required certificates have been checked) in any context.  For
-- example, array indexing is not safe, as the index may be out of
-- bounds.  On the other hand, adding two numbers cannot fail.
safeExp :: IsOp (Op lore) => Exp lore -> Bool
safeExp (BasicOp op) = safeBasicOp op
  where safeBasicOp (BinOp SDiv{} _ (Constant y)) = not $ zeroIsh y
        safeBasicOp (BinOp SDiv{} _ _) = False
        safeBasicOp (BinOp UDiv{} _ (Constant y)) = not $ zeroIsh y
        safeBasicOp (BinOp UDiv{} _ _) = False
        safeBasicOp (BinOp SMod{} _ (Constant y)) = not $ zeroIsh y
        safeBasicOp (BinOp SMod{} _ _) = False
        safeBasicOp (BinOp UMod{} _ (Constant y)) = not $ zeroIsh y
        safeBasicOp (BinOp UMod{} _ _) = False

        safeBasicOp (BinOp SQuot{} _ (Constant y)) = not $ zeroIsh y
        safeBasicOp (BinOp SQuot{} _ _) = False
        safeBasicOp (BinOp SRem{} _ (Constant y)) = not $ zeroIsh y
        safeBasicOp (BinOp SRem{} _ _) = False

        safeBasicOp (BinOp Pow{} _ (Constant y)) = not $ negativeIsh y
        safeBasicOp (BinOp Pow{} _ _) = False
        safeBasicOp ArrayLit{} = True
        safeBasicOp BinOp{} = True
        safeBasicOp SubExp{} = True
        safeBasicOp UnOp{} = True
        safeBasicOp CmpOp{} = True
        safeBasicOp ConvOp{} = True
        safeBasicOp Scratch{} = True
        safeBasicOp Concat{} = True
        safeBasicOp Reshape{} = True
        safeBasicOp Manifest{} = True
        safeBasicOp _ = False

safeExp (DoLoop _ _ _ body) = safeBody body
safeExp (Apply fname _ _ _) = isBuiltInFunction fname
safeExp (If _ tbranch fbranch _) =
  all (safeExp . stmExp) (bodyStms tbranch) &&
  all (safeExp . stmExp) (bodyStms fbranch)
safeExp (Op op) = safeOp op
{'fraction_non_alphanumeric': 0.09397800283131874, 'fraction_numerical': 0.0, 'mean_word_length': 3.69769820971867, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 15, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3738839', 'n_tokens_mistral': 2886, 'n_tokens_neox': 2839, 'n_words': 832}