<commit_before>-- Enumeration of function mutations
module Mutate
  ( Mutable (..)
  , lsMutantsEq
  , mutantsIntegral
  )
where

import Test.Check
import Test.Check.Utils
import Data.List (intercalate, delete)
import Data.Maybe
import Utils (errorToNothing)

-- The first mutant returned by szMutants and mutants is the actual function
-- without mutation.
class Mutable a where
  lsMutants :: a -> [[a]]
  mutants :: a -> [a]
  lsMutants = map (:[]) . mutants
  mutants = concat . lsMutants

-- Beware: if the underlying enumeration for argument/return values generates
-- repeated elements there will be repeated and potentially null mutants.
instance (Eq a, Listable a, Mutable b) => Mutable (a -> b) where
  lsMutants f = lsmap (defaultFunPairsToFunction f)
              $ lsConcatMap (`associations'` mutantsFor)
              $ lsCrescListsOf listing
    where mutantsFor x = case errorToNothing (f x) of
                           Nothing -> [[]]
                           Just fx -> tail (lsMutants fx)

lsdelete :: Eq a => a -> [[a]] -> [[a]]
lsdelete x = map (delete x)

-- TODO: Possible Optimization: (deleteOnce x)
lsMutantsEq :: (Listable a, Eq a) => a -> [[a]]
lsMutantsEq x = [x] : lsdelete x listing

-- Mutants of an Integral value.  Always start towards zero.  Alternating
-- between sucessor and predecessor.
-- The tail usage is there to avoid generating out of bound values.
-- (x-1) is usually safe though.
mutantsIntegral :: Integral a => a -> [a]
mutantsIntegral i | i > 0     = [i..] \/ tail [i,(i-1)..]
                  | otherwise = [i,(i-1)..] \/ tail [i..]

instance Mutable ()   where lsMutants = lsMutantsEq
--instance Mutable Int  where mutants = mutantsIntegral
instance Mutable Int  where lsMutants = lsMutantsEq
instance Mutable Char where lsMutants = lsMutantsEq
instance Mutable Bool where lsMutants = lsMutantsEq
instance (Eq a, Listable a) => Mutable [a]       where lsMutants = lsMutantsEq
instance (Eq a, Listable a) => Mutable (Maybe a) where lsMutants = lsMutantsEq

{- Alternative implementation for Mutable lists:
instance (Listable a, Mutable a) => Mutable [a]
  where lsMutants []     = [ [] ]
                         : [ ]
                         : tail listing
        lsMutants (x:xs) = [ (x:xs) ]
                         : [ [] ]
                         : tail (lsProductWith (:) (lsMutants x) (lsMutants xs))<commit_msg>black: normalize after deleting in lsdelete<commit_after>-- Enumeration of function mutations
module Mutate
  ( Mutable (..)
  , lsMutantsEq
  , mutantsIntegral
  )
where

import Test.Check
import Test.Check.Utils
import Data.List (intercalate, delete)
import Data.Maybe
import Utils (errorToNothing)

-- The first mutant returned by szMutants and mutants is the actual function
-- without mutation.
class Mutable a where
  lsMutants :: a -> [[a]]
  mutants :: a -> [a]
  lsMutants = map (:[]) . mutants
  mutants = concat . lsMutants

-- Beware: if the underlying enumeration for argument/return values generates
-- repeated elements there will be repeated and potentially null mutants.
instance (Eq a, Listable a, Mutable b) => Mutable (a -> b) where
  lsMutants f = lsmap (defaultFunPairsToFunction f)
              $ lsConcatMap (`associations'` mutantsFor)
              $ lsCrescListsOf listing
    where mutantsFor x = case errorToNothing (f x) of
                           Nothing -> [[]]
                           Just fx -> tail (lsMutants fx)

lsdelete :: Eq a => a -> [[a]] -> [[a]]
lsdelete x = lsnormalize . map (delete x)
  where lsnormalize []       = []
        lsnormalize [[]]     = []
        lsnormalize (xs:xss) = xs:lsnormalize xss

-- TODO: Possible Optimization: (deleteOnce x)
lsMutantsEq :: (Listable a, Eq a) => a -> [[a]]
lsMutantsEq x = [x] : lsdelete x listing

-- Mutants of an Integral value.  Always start towards zero.  Alternating
-- between sucessor and predecessor.
-- The tail usage is there to avoid generating out of bound values.
-- (x-1) is usually safe though.
mutantsIntegral :: Integral a => a -> [a]
mutantsIntegral i | i > 0     = [i..] \/ tail [i,(i-1)..]
                  | otherwise = [i,(i-1)..] \/ tail [i..]

instance Mutable ()   where lsMutants = lsMutantsEq
--instance Mutable Int  where mutants = mutantsIntegral
instance Mutable Int  where lsMutants = lsMutantsEq
instance Mutable Char where lsMutants = lsMutantsEq
instance Mutable Bool where lsMutants = lsMutantsEq
instance (Eq a, Listable a) => Mutable [a]       where lsMutants = lsMutantsEq
instance (Eq a, Listable a) => Mutable (Maybe a) where lsMutants = lsMutantsEq

{- Alternative implementation for Mutable lists:
instance (Listable a, Mutable a) => Mutable [a]
  where lsMutants []     = [ [] ]
                         : [ ]
                         : tail listing
        lsMutants (x:xs) = [ (x:xs) ]
                         : [ [] ]
                         : tail (lsProductWith (:) (lsMutants x) (lsMutants xs))
{'fraction_non_alphanumeric': 0.109463850528026, 'fraction_numerical': 0.0016246953696181965, 'mean_word_length': 2.5714285714285716, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 37, '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': '1822764', 'n_tokens_mistral': 1566, 'n_tokens_neox': 1459, 'n_words': 530}