{-# Language TemplateHaskell #-}
module Language.Drasil.Chunk.UnitDefn (
MayHaveUnit(getUnit),
IsUnit(getUnits),
TempHasUnit(findUnit),
UnitDefn(..),
makeDerU, newUnit,
derUC, derUC', derUC'',
fund, fund', derCUC, derCUC', derCUC'',
unitWrapper,
(^:), (/:), (*:), (*$), (/$), (^$),
scale, shift,
fromUDefn, unitCon, getCu, compUnitDefn
) where
import Control.Lens ((^.), makeLenses, view)
import Control.Arrow (second)
import Language.Drasil.Chunk.Concept (ConceptChunk, dcc, cc')
import Language.Drasil.Classes (NamedIdea(term), Idea(getA),
Definition(defn), ConceptDomain(cdom), HasUnitSymbol(usymb), IsUnit(udefn, getUnits))
import Language.Drasil.NounPhrase (cn,cn',NP)
import Language.Drasil.Symbol (Symbol(Label))
import Language.Drasil.UnitLang (USymb(US), UDefn(UScale, USynonym, UShift),
compUSymb, fromUDefn, getUSymb, getDefn, UnitSymbol(BaseSI, DerivedSI, Defined))
import Language.Drasil.UID (UID, HasUID(..), mkUid)
data UnitDefn = UD { UnitDefn -> ConceptChunk
_vc :: ConceptChunk
, UnitDefn -> UnitSymbol
_cas :: UnitSymbol
, UnitDefn -> [UID]
_cu :: [UID] }
makeLenses ''UnitDefn
instance HasUID UnitDefn where uid :: Lens' UnitDefn UID
uid = Lens' UnitDefn ConceptChunk
vc forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall c. HasUID c => Lens' c UID
uid
instance NamedIdea UnitDefn where term :: Lens' UnitDefn NP
term = Lens' UnitDefn ConceptChunk
vc forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall c. NamedIdea c => Lens' c NP
term
instance Idea UnitDefn where getA :: UnitDefn -> Maybe String
getA UnitDefn
c = forall c. Idea c => c -> Maybe String
getA (UnitDefn
c forall s a. s -> Getting a s a -> a
^. Lens' UnitDefn ConceptChunk
vc)
instance Definition UnitDefn where defn :: Lens' UnitDefn Sentence
defn = Lens' UnitDefn ConceptChunk
vc forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall c. Definition c => Lens' c Sentence
defn
instance Eq UnitDefn where UnitDefn
a == :: UnitDefn -> UnitDefn -> Bool
== UnitDefn
b = forall u. HasUnitSymbol u => u -> USymb
usymb UnitDefn
a forall a. Eq a => a -> a -> Bool
== forall u. HasUnitSymbol u => u -> USymb
usymb UnitDefn
b
instance ConceptDomain UnitDefn where cdom :: UnitDefn -> [UID]
cdom = forall c. ConceptDomain c => c -> [UID]
cdom forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall s (m :: * -> *) a. MonadReader s m => Getting a s a -> m a
view Lens' UnitDefn ConceptChunk
vc
instance HasUnitSymbol UnitDefn where usymb :: UnitDefn -> USymb
usymb = UnitSymbol -> USymb
getUSymb forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall s (m :: * -> *) a. MonadReader s m => Getting a s a -> m a
view Lens' UnitDefn UnitSymbol
cas
instance IsUnit UnitDefn where
udefn :: UnitDefn -> Maybe UDefn
udefn = UnitSymbol -> Maybe UDefn
getDefn forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall s (m :: * -> *) a. MonadReader s m => Getting a s a -> m a
view Lens' UnitDefn UnitSymbol
cas
getUnits :: UnitDefn -> [UID]
getUnits = forall s (m :: * -> *) a. MonadReader s m => Getting a s a -> m a
view Lens' UnitDefn [UID]
cu
class MayHaveUnit u where
getUnit :: u -> Maybe UnitDefn
class TempHasUnit u where
findUnit :: u -> UnitDefn
data UnitEquation = UE {UnitEquation -> [UID]
_contributingUnit :: [UID]
, UnitEquation -> USymb
_us :: USymb}
makeLenses ''UnitEquation
instance HasUnitSymbol UnitEquation where usymb :: UnitEquation -> USymb
usymb UnitEquation
u = UnitEquation
u forall s a. s -> Getting a s a -> a
^. Lens' UnitEquation USymb
us
getCu :: UnitEquation -> [UID]
getCu :: UnitEquation -> [UID]
getCu = forall s (m :: * -> *) a. MonadReader s m => Getting a s a -> m a
view Lens' UnitEquation [UID]
contributingUnit
makeDerU :: ConceptChunk -> UnitEquation -> UnitDefn
makeDerU :: ConceptChunk -> UnitEquation -> UnitDefn
makeDerU ConceptChunk
concept UnitEquation
eqn = ConceptChunk -> UnitSymbol -> [UID] -> UnitDefn
UD ConceptChunk
concept (USymb -> UDefn -> UnitSymbol
Defined (forall u. HasUnitSymbol u => u -> USymb
usymb UnitEquation
eqn) (USymb -> UDefn
USynonym forall a b. (a -> b) -> a -> b
$ forall u. HasUnitSymbol u => u -> USymb
usymb UnitEquation
eqn)) (UnitEquation -> [UID]
getCu UnitEquation
eqn)
derCUC, derCUC' :: String -> String -> String -> Symbol -> UnitEquation -> UnitDefn
derCUC :: String -> String -> String -> Symbol -> UnitEquation -> UnitDefn
derCUC String
a String
b String
c Symbol
s UnitEquation
ue = ConceptChunk -> UnitSymbol -> [UID] -> UnitDefn
UD (String -> NP -> String -> ConceptChunk
dcc String
a (String -> NP
cn String
b) String
c) (USymb -> USymb -> UDefn -> UnitSymbol
DerivedSI ([(Symbol, Integer)] -> USymb
US [(Symbol
s,Integer
1)]) (forall u. HasUnitSymbol u => u -> USymb
usymb UnitEquation
ue) (USymb -> UDefn
USynonym forall a b. (a -> b) -> a -> b
$ forall u. HasUnitSymbol u => u -> USymb
usymb UnitEquation
ue)) [String -> UID
mkUid String
a]
derCUC' :: String -> String -> String -> Symbol -> UnitEquation -> UnitDefn
derCUC' String
a String
b String
c Symbol
s UnitEquation
ue = ConceptChunk -> UnitSymbol -> [UID] -> UnitDefn
UD (String -> NP -> String -> ConceptChunk
dcc String
a (String -> NP
cn' String
b) String
c) (USymb -> USymb -> UDefn -> UnitSymbol
DerivedSI ([(Symbol, Integer)] -> USymb
US [(Symbol
s,Integer
1)]) (forall u. HasUnitSymbol u => u -> USymb
usymb UnitEquation
ue) (USymb -> UDefn
USynonym forall a b. (a -> b) -> a -> b
$ forall u. HasUnitSymbol u => u -> USymb
usymb UnitEquation
ue)) [String -> UID
mkUid String
a]
derUC, derUC' :: String -> String -> String -> Symbol -> UDefn -> UnitDefn
derUC :: String -> String -> String -> Symbol -> UDefn -> UnitDefn
derUC String
a String
b String
c Symbol
s UDefn
u = ConceptChunk -> UnitSymbol -> [UID] -> UnitDefn
UD (String -> NP -> String -> ConceptChunk
dcc String
a (String -> NP
cn String
b) String
c) (USymb -> USymb -> UDefn -> UnitSymbol
DerivedSI ([(Symbol, Integer)] -> USymb
US [(Symbol
s,Integer
1)]) (UDefn -> USymb
fromUDefn UDefn
u) UDefn
u) []
derUC' :: String -> String -> String -> Symbol -> UDefn -> UnitDefn
derUC' String
a String
b String
c Symbol
s UDefn
u = ConceptChunk -> UnitSymbol -> [UID] -> UnitDefn
UD (String -> NP -> String -> ConceptChunk
dcc String
a (String -> NP
cn' String
b) String
c) (USymb -> USymb -> UDefn -> UnitSymbol
DerivedSI ([(Symbol, Integer)] -> USymb
US [(Symbol
s,Integer
1)]) (UDefn -> USymb
fromUDefn UDefn
u) UDefn
u) []
derCUC'' :: String -> NP -> String -> Symbol -> UnitEquation -> UnitDefn
derCUC'' :: String -> NP -> String -> Symbol -> UnitEquation -> UnitDefn
derCUC'' String
a NP
b String
c Symbol
s UnitEquation
ue = ConceptChunk -> UnitSymbol -> [UID] -> UnitDefn
UD (String -> NP -> String -> ConceptChunk
dcc String
a NP
b String
c) (USymb -> USymb -> UDefn -> UnitSymbol
DerivedSI ([(Symbol, Integer)] -> USymb
US [(Symbol
s,Integer
1)]) (forall u. HasUnitSymbol u => u -> USymb
usymb UnitEquation
ue) (USymb -> UDefn
USynonym forall a b. (a -> b) -> a -> b
$ forall u. HasUnitSymbol u => u -> USymb
usymb UnitEquation
ue)) (UnitEquation -> [UID]
getCu UnitEquation
ue)
derUC'' :: String -> NP -> String -> Symbol -> UDefn -> UnitDefn
derUC'' :: String -> NP -> String -> Symbol -> UDefn -> UnitDefn
derUC'' String
a NP
b String
c Symbol
s UDefn
u = ConceptChunk -> UnitSymbol -> [UID] -> UnitDefn
UD (String -> NP -> String -> ConceptChunk
dcc String
a NP
b String
c) (USymb -> USymb -> UDefn -> UnitSymbol
DerivedSI ([(Symbol, Integer)] -> USymb
US [(Symbol
s,Integer
1)]) (UDefn -> USymb
fromUDefn UDefn
u) UDefn
u) []
unitCon :: String -> ConceptChunk
unitCon :: String -> ConceptChunk
unitCon String
s = String -> NP -> String -> ConceptChunk
dcc String
s (String -> NP
cn' String
s) String
s
unitWrapper :: (IsUnit u) => u -> UnitDefn
unitWrapper :: forall u. IsUnit u => u -> UnitDefn
unitWrapper u
u = ConceptChunk -> UnitSymbol -> [UID] -> UnitDefn
UD (forall c. Idea c => c -> Sentence -> ConceptChunk
cc' u
u (u
u forall s a. s -> Getting a s a -> a
^. forall c. Definition c => Lens' c Sentence
defn)) (USymb -> UDefn -> UnitSymbol
Defined (forall u. HasUnitSymbol u => u -> USymb
usymb u
u) (USymb -> UDefn
USynonym forall a b. (a -> b) -> a -> b
$ forall u. HasUnitSymbol u => u -> USymb
usymb u
u)) (forall u. IsUnit u => u -> [UID]
getUnits u
u)
getSecondSymb :: UnitDefn -> Maybe USymb
getSecondSymb :: UnitDefn -> Maybe USymb
getSecondSymb UnitDefn
c = UnitSymbol -> Maybe USymb
get_symb2 forall a b. (a -> b) -> a -> b
$ forall s (m :: * -> *) a. MonadReader s m => Getting a s a -> m a
view Lens' UnitDefn UnitSymbol
cas UnitDefn
c
where
get_symb2 :: UnitSymbol -> Maybe USymb
get_symb2 :: UnitSymbol -> Maybe USymb
get_symb2 (BaseSI USymb
_) = forall a. Maybe a
Nothing
get_symb2 (DerivedSI USymb
_ USymb
v UDefn
_) = forall a. a -> Maybe a
Just USymb
v
get_symb2 (Defined USymb
_ UDefn
_) = forall a. Maybe a
Nothing
helperUnit :: UnitDefn -> [UID]
helperUnit :: UnitDefn -> [UID]
helperUnit UnitDefn
a = case UnitDefn -> Maybe USymb
getSecondSymb UnitDefn
a of
Just USymb
_ -> [UnitDefn
a forall s a. s -> Getting a s a -> a
^. forall c. HasUID c => Lens' c UID
uid]
Maybe USymb
Nothing -> forall u. IsUnit u => u -> [UID]
getUnits UnitDefn
a
(^:) :: UnitDefn -> Integer -> UnitEquation
UnitDefn
u ^: :: UnitDefn -> Integer -> UnitEquation
^: Integer
i = [UID] -> USymb -> UnitEquation
UE (UnitDefn -> [UID]
helperUnit UnitDefn
u) (USymb -> USymb
upow (forall u. HasUnitSymbol u => u -> USymb
usymb UnitDefn
u))
where
upow :: USymb -> USymb
upow (US [(Symbol, Integer)]
l) = [(Symbol, Integer)] -> USymb
US forall a b. (a -> b) -> a -> b
$ forall a b. (a -> b) -> [a] -> [b]
map (forall (a :: * -> * -> *) b c d.
Arrow a =>
a b c -> a (d, b) (d, c)
second (forall a. Num a => a -> a -> a
* Integer
i)) [(Symbol, Integer)]
l
(/:) :: UnitDefn -> UnitDefn -> UnitEquation
UnitDefn
u1 /: :: UnitDefn -> UnitDefn -> UnitEquation
/: UnitDefn
u2 = let US [(Symbol, Integer)]
l1 = forall u. HasUnitSymbol u => u -> USymb
usymb UnitDefn
u1
US [(Symbol, Integer)]
l2 = forall u. HasUnitSymbol u => u -> USymb
usymb UnitDefn
u2 in
[UID] -> USymb -> UnitEquation
UE (UnitDefn -> [UID]
helperUnit UnitDefn
u1 forall a. [a] -> [a] -> [a]
++ UnitDefn -> [UID]
helperUnit UnitDefn
u2) ([(Symbol, Integer)] -> USymb
US forall a b. (a -> b) -> a -> b
$ [(Symbol, Integer)]
l1 forall a. [a] -> [a] -> [a]
++ forall a b. (a -> b) -> [a] -> [b]
map (forall (a :: * -> * -> *) b c d.
Arrow a =>
a b c -> a (d, b) (d, c)
second forall a. Num a => a -> a
negate) [(Symbol, Integer)]
l2)
(*:) :: UnitDefn -> UnitDefn -> UnitEquation
UnitDefn
u1 *: :: UnitDefn -> UnitDefn -> UnitEquation
*: UnitDefn
u2 = let US [(Symbol, Integer)]
l1 = forall u. HasUnitSymbol u => u -> USymb
usymb UnitDefn
u1
US [(Symbol, Integer)]
l2 = forall u. HasUnitSymbol u => u -> USymb
usymb UnitDefn
u2 in
[UID] -> USymb -> UnitEquation
UE (UnitDefn -> [UID]
helperUnit UnitDefn
u1 forall a. [a] -> [a] -> [a]
++ UnitDefn -> [UID]
helperUnit UnitDefn
u2) ([(Symbol, Integer)] -> USymb
US forall a b. (a -> b) -> a -> b
$ [(Symbol, Integer)]
l1 forall a. [a] -> [a] -> [a]
++ [(Symbol, Integer)]
l2)
(*$) :: UnitDefn -> UnitEquation -> UnitEquation
UnitDefn
u1 *$ :: UnitDefn -> UnitEquation -> UnitEquation
*$ UnitEquation
u2 = let US [(Symbol, Integer)]
l1 = forall u. HasUnitSymbol u => u -> USymb
usymb UnitDefn
u1
US [(Symbol, Integer)]
l2 = forall u. HasUnitSymbol u => u -> USymb
usymb UnitEquation
u2 in
[UID] -> USymb -> UnitEquation
UE (UnitDefn -> [UID]
helperUnit UnitDefn
u1 forall a. [a] -> [a] -> [a]
++ UnitEquation -> [UID]
getCu UnitEquation
u2) ([(Symbol, Integer)] -> USymb
US forall a b. (a -> b) -> a -> b
$ [(Symbol, Integer)]
l1 forall a. [a] -> [a] -> [a]
++ [(Symbol, Integer)]
l2)
(/$) :: UnitDefn -> UnitEquation -> UnitEquation
UnitDefn
u1 /$ :: UnitDefn -> UnitEquation -> UnitEquation
/$ UnitEquation
u2 = let US [(Symbol, Integer)]
l1 = forall u. HasUnitSymbol u => u -> USymb
usymb UnitDefn
u1
US [(Symbol, Integer)]
l2 = forall u. HasUnitSymbol u => u -> USymb
usymb UnitEquation
u2 in
[UID] -> USymb -> UnitEquation
UE (UnitDefn -> [UID]
helperUnit UnitDefn
u1 forall a. [a] -> [a] -> [a]
++ UnitEquation -> [UID]
getCu UnitEquation
u2) ([(Symbol, Integer)] -> USymb
US forall a b. (a -> b) -> a -> b
$ [(Symbol, Integer)]
l1 forall a. [a] -> [a] -> [a]
++ forall a b. (a -> b) -> [a] -> [b]
map (forall (a :: * -> * -> *) b c d.
Arrow a =>
a b c -> a (d, b) (d, c)
second forall a. Num a => a -> a
negate) [(Symbol, Integer)]
l2)
(^$) :: UnitEquation -> UnitEquation -> UnitEquation
UnitEquation
u1 ^$ :: UnitEquation -> UnitEquation -> UnitEquation
^$ UnitEquation
u2 = let US [(Symbol, Integer)]
l1 = forall u. HasUnitSymbol u => u -> USymb
usymb UnitEquation
u1
US [(Symbol, Integer)]
l2 = forall u. HasUnitSymbol u => u -> USymb
usymb UnitEquation
u2 in
[UID] -> USymb -> UnitEquation
UE (UnitEquation -> [UID]
getCu UnitEquation
u1 forall a. [a] -> [a] -> [a]
++ UnitEquation -> [UID]
getCu UnitEquation
u2) ([(Symbol, Integer)] -> USymb
US forall a b. (a -> b) -> a -> b
$ [(Symbol, Integer)]
l1 forall a. [a] -> [a] -> [a]
++ [(Symbol, Integer)]
l2)
scale :: IsUnit s => Double -> s -> UDefn
scale :: forall s. IsUnit s => Double -> s -> UDefn
scale Double
a s
b = Double -> USymb -> UDefn
UScale Double
a (forall u. HasUnitSymbol u => u -> USymb
usymb s
b)
shift :: IsUnit s => Double -> s -> UDefn
shift :: forall s. IsUnit s => Double -> s -> UDefn
shift Double
a s
b = Double -> USymb -> UDefn
UShift Double
a (forall u. HasUnitSymbol u => u -> USymb
usymb s
b)
newUnit :: String -> UnitEquation -> UnitDefn
newUnit :: String -> UnitEquation -> UnitDefn
newUnit String
s = ConceptChunk -> UnitEquation -> UnitDefn
makeDerU (String -> ConceptChunk
unitCon String
s)
fund :: String -> String -> String -> UnitDefn
fund :: String -> String -> String -> UnitDefn
fund String
nam String
desc String
sym = ConceptChunk -> UnitSymbol -> [UID] -> UnitDefn
UD (String -> NP -> String -> ConceptChunk
dcc String
nam (String -> NP
cn' String
nam) String
desc) (USymb -> UnitSymbol
BaseSI forall a b. (a -> b) -> a -> b
$ [(Symbol, Integer)] -> USymb
US [(String -> Symbol
Label String
sym, Integer
1)]) [String -> UID
mkUid String
nam]
fund' :: String -> String -> Symbol -> UnitDefn
fund' :: String -> String -> Symbol -> UnitDefn
fund' String
nam String
desc Symbol
sym = ConceptChunk -> UnitSymbol -> [UID] -> UnitDefn
UD (String -> NP -> String -> ConceptChunk
dcc String
nam (String -> NP
cn' String
nam) String
desc) (USymb -> UnitSymbol
BaseSI forall a b. (a -> b) -> a -> b
$ [(Symbol, Integer)] -> USymb
US [(Symbol
sym, Integer
1)]) [String -> UID
mkUid String
nam]
compUnitDefn :: UnitDefn -> UnitDefn -> Ordering
compUnitDefn :: UnitDefn -> UnitDefn -> Ordering
compUnitDefn UnitDefn
a UnitDefn
b = USymb -> USymb -> Ordering
compUSymb (forall u. HasUnitSymbol u => u -> USymb
usymb UnitDefn
a) (forall u. HasUnitSymbol u => u -> USymb
usymb UnitDefn
b)