huzzy-0.1.0.0: src/Huzzy/Base/Sets.hs
module Huzzy.Base.Sets where
newtype MF a = MF (a -> Double)
type MF' a = a -> Double
type FuzOp a = a -> a -> a
class Fuzzy a where
(?&&) :: a -> a -> a
(?||) :: a -> a -> a
fnot :: a -> a
instance Fuzzy Double where
(?&&) = max
(?||) = min
fnot x = 1 - x
instance (Fuzzy b) => Fuzzy (a -> b) where
f ?&& g = \x -> f x ?&& g x
f ?|| g = \x -> f x ?|| g x
fnot f = fnot (\x -> f x)
instance Fuzzy (MF a) where
(MF f) ?&& (MF g) = MF (f ?&& g)
(MF f) ?|| (MF g) = MF (f ?|| g)
fnot (MF f) = MF (fnot f)
instance (Fuzzy a, Fuzzy b) => Fuzzy (a, b) where
(a, b) ?&& (c, d) = (a ?&& c, b ?&& d)
(a ,b) ?|| (c, d) = (a ?|| c, b ?|| d)
fnot (a, b) = (fnot a, fnot b)
class FSet a where
type Value a
type Support a
type Returned a
support :: a -> Support a
hedge :: Double -> a -> a
is :: Value a -> a -> Returned a
{-
class FSet a b c d | a -> b, a -> c, a -> d where
support :: a -> [c]
hedge :: Double -> a -> a
is :: b -> a -> d
-}
tNo :: Fuzzy a => FuzOp a -> a -> a -> a
tNo op = op
tCo :: (Num a, Fuzzy a) => FuzOp a -> a -> a -> a
tCo tNo a b = (-) 1 $ tNo (1 - a) (1 - b)
tGodel :: (Fuzzy a, Ord a) => FuzOp a
tGodel = min
tProd :: (Fuzzy a, Num a) => FuzOp a
tProd = (*)
tLuk :: (Fuzzy a, Num a, Ord a) => FuzOp a
tLuk a b = max 0 (a + b - 1)
tDras :: (Fuzzy a, Eq a, Num a) => FuzOp a
tDras a b | a == 1 = b
| b == 1 = a
| otherwise = 0
tNilMin :: (Fuzzy a, Eq a, Num a, Ord a) => FuzOp a
tNilMin a b | a + b > 1 = min a b
| otherwise = 0
tHam :: (Fuzzy a, Eq a, Num a, Fractional a) => FuzOp a
tHam a b | a == b && b == 0 = 0
| otherwise = a*b/a+b-a*b
support' :: [a] -> MF' a -> [a]
support' xs f = filter (\x -> f x > 0) xs
hedge' :: Double -> MF' a -> MF' a
hedge' p f x | f x == 0 = 0
| otherwise = f x ** p
approximate' :: Double -> Double -> [Double] -> MF' Double
approximate' fuzziness n dom = tri' a b c
where hw = fuzziness * (ub' dom - lb' dom)
a = (n - hw)
b = (n+hw)
c = b-((b-a)*0.5)
ub', lb' :: Ord a => [a] -> a
ub' = maximum
lb' = maximum
very', extremely', somewhat', slightly' :: MF' a -> MF' a
very' = hedge' 2
extremely' = hedge' 3
somewhat' = hedge' 0.5
slightly' = hedge' (1/3)
discrete :: Eq a => [(a, Double)] -> MF a
discrete vs = MF (\x -> discrete' vs x)
discrete' :: Eq a => [(a, Double)] -> MF' a
discrete' vs x = case lookup x vs of
Just t -> t
Nothing -> 0
singleton :: Double -> MF a
singleton d = MF (\x -> singleton' d x)
singleton' :: Double -> MF' a
singleton' d x = d
up :: Double -> Double -> MF Double
up a b = MF (\x -> up' a b x)
up' :: Double -> Double -> MF' Double
up' a b x
| x < a = 0
| x < b = (x - a) / (b - a)
| otherwise = 1
tri :: Double -> Double -> Double -> MF Double
tri a b c = MF (\x -> tri' a b c x)
tri' :: Double -> Double -> Double -> MF' Double
tri' a b c x | x <= a = 0
| a <= x && x <= b = (x-a)/(b-a)
| b <= x && x <= c = (c-x)/(c-b)
| c <= x = 0
trap :: Double -> Double -> Double -> Double -> MF Double
trap a b c d = MF (\x -> trap' a b c d x)
trap' :: Double -> Double -> Double -> Double -> MF' Double
trap' a b c d x | x <= a || d <= x = 0
| a <= x && x <= b = (x-a)/(b-a)
| b <= x && x <= c = 1
| c <= x && x <= d = (d-x)/(d-c)
| otherwise = 0
gaus :: Double -> Double -> MF Double
gaus sig c = MF (\x -> gaus' sig c x)
gaus' :: Double -> Double -> MF' Double
gaus' sig c x = let e = exp 1 in e**((-0.5*(x-c/sig))**2)
bell :: Double -> Double -> Double -> MF Double
bell a b c = MF (\x -> bell' a b c x)
bell' :: Double -> Double -> Double -> MF' Double
bell' a b c x = 1/(1+abs ((x-c/a)**2*b))
sig :: Double -> Double -> MF Double
sig a c = MF (\x -> sig' a c x)
sig' :: Double -> Double -> MF' Double
sig' a c x = 1/(1+exp(-a*(x-c)))
-- Probably shit
cyl' :: Double -> Double -> MF' Double
cyl' a b x | sqrt (a**2 + b**2) <= x = 1
| sqrt (a**2 + b**2) > x = 0