module Huzzy.TypeOne.Sets
( T1Set(mf, dom)
, Fuzzy(..)
, FSet(..)
, contT1
, discT1
, unsafeMkT1
, alpha
, findCuts
)where
import Data.List(sortBy, nub, elemIndex)
import Data.Maybe(fromJust)
import Huzzy.Base.Sets
data T1Set a = T1S { mf :: MF a
, dom :: [a]
}
instance Fuzzy (T1Set a) where
a ?&& b = a { mf = (mf a) ?&& (mf b)}
a ?|| b = a { mf = (mf a) ?|| (mf b)}
fnot a = a { mf = fnot (mf a)}
instance FSet (T1Set a) where
type Value (T1Set a) = a
type Support (T1Set a) = [a]
type Returned (T1Set a) = Double
support s = filter (\x -> (x `is` s) > 0) d
where
d = dom s
hedge p s = s {mf = MF (\x -> mf' x)}
where
(MF f) = mf s
mf' x | f x == 0 = 0
| otherwise = f x ** p
x `is` s = f x
where
(MF f) = mf s
instance Num (T1Set a) where
a + b = a { mf = (mf a) + (mf b)}
a * b = a { mf = (mf a) * (mf b)}
a b = a { mf = (mf a) * (mf b)}
abs a = a { mf = abs (mf a)}
signum a = a {mf = signum (mf a)}
fromInteger n = T1S { mf = MF $ \x -> fromInteger n
, dom = [] }
contT1 :: (Num a, Enum a) => a -> a -> a -> MF a -> T1Set a
contT1 minB maxB res (MF mf) = case check of
True -> error "Truth values must be in the range [0..1]"
False -> T1S { mf = MF mf
, dom = domain
}
where
domain = [minB, minB+res .. maxB]
check = any (\x -> x > 1 || x < 0) (map mf domain)
discT1 :: [a] -> MF a -> T1Set a
discT1 dom (MF mf) = case check of
True -> error "Truth values must be in the range [0..1]"
False -> T1S { mf = MF mf
, dom = dom
}
where
check = any (\x -> x > 1 || x < 0) (map mf dom)
unsafeMkT1 :: [a] -> MF a -> T1Set a
unsafeMkT1 dom mf = T1S { mf = mf
, dom = dom
}
alpha :: Double -> T1Set a -> [a]
alpha d s = filter (\x -> f x >= d) (dom s)
where
(MF f) = mf s
findCuts :: Ord a => T1Set a -> Double -> (a, a)
findCuts s d = (l, r)
where
as = alpha d s
l = maximum as
li = fromJust $ elemIndex l as
r = maximum (snd $ splitAt li as)