-- | Defines theories in the field of Physics.
module Data.Drasil.Theories.Physics where

import Language.Drasil
import Utils.Drasil (weave)
import Theory.Drasil
import qualified Language.Drasil.Sentence.Combinators as S

import Data.Drasil.Citations (velocityWiki, accelerationWiki)
import Data.Drasil.Concepts.Documentation (component, material_, value, constant)
import Data.Drasil.Concepts.Math (cartesian, equation, vector)
import Data.Drasil.Concepts.Physics (gravity, twoD, rigidBody)
import qualified Data.Drasil.Quantities.PhysicalProperties as QPP (density, 
  mass, specWeight, vol)
import qualified Data.Drasil.Quantities.Physics as QP (acceleration, velocity, position,
  force, gravitationalAccel, pressure, torque, weight, positionVec, time, momentOfInertia,
  angularAccel, speed)
import Data.Drasil.Equations.Defining.Physics
import Data.Drasil.Equations.Defining.Derivations

-- | Collects theoretical models defined in this file.
physicsTMs :: [TheoryModel]
physicsTMs :: [TheoryModel]
physicsTMs = [TheoryModel
newtonSL]

-- * Newton's Second Law of Motion

newtonSL :: TheoryModel
newtonSL :: TheoryModel
newtonSL = forall q c.
(Quantity q, MayHaveUnit q, Concept c) =>
ModelKind ModelExpr
-> [q]
-> [c]
-> [ModelQDef]
-> [ModelExpr]
-> [ModelQDef]
-> String
-> [Sentence]
-> TheoryModel
tmNoRefs (forall e. String -> QDefinition e -> ModelKind e
equationalModelU String
"newtonSL" ModelQDef
newtonSLQD)
  [forall q. (Quantity q, MayHaveUnit q) => q -> QuantityDict
qw UnitalChunk
QP.force, forall q. (Quantity q, MayHaveUnit q) => q -> QuantityDict
qw UnitalChunk
QPP.mass, forall q. (Quantity q, MayHaveUnit q) => q -> QuantityDict
qw UnitalChunk
QP.acceleration] ([] :: [ConceptChunk])
  [ModelQDef
newtonSLQD] [] [] String
"NewtonSecLawMot" [Sentence
newtonSLDesc]

-- * Weight

weightGD :: GenDefn
weightGD :: GenDefn
weightGD = forall u.
IsUnit u =>
ModelKind ModelExpr
-> Maybe u
-> Maybe Derivation
-> [DecRef]
-> String
-> [Sentence]
-> GenDefn
gd (forall e. QDefinition e -> ModelKind e
equationalModel' ModelQDef
weightQD) (forall u. MayHaveUnit u => u -> Maybe UnitDefn
getUnit UnitalChunk
QP.weight) (forall a. a -> Maybe a
Just Derivation
weightDeriv) [forall r.
(HasUID r, HasRefAddress r, HasShortName r) =>
r -> DecRef
dRef Reference
weightSrc] 
  String
"weight" [{-Notes-}]

weightQD :: ModelQDef
weightQD :: ModelQDef
weightQD = forall c e.
(Quantity c, MayHaveUnit c) =>
c -> NP -> e -> QDefinition e
mkQuantDef' UnitalChunk
QP.weight (String -> NP
nounPhraseSP String
"weight") forall r. ExprC r => r
weightEqn

weightSrc :: Reference
weightSrc :: Reference
weightSrc = String -> String -> ShortName -> Reference
makeURI String
"weightSrc" String
"https://en.wikipedia.org/wiki/Weight" forall a b. (a -> b) -> a -> b
$
  Sentence -> ShortName
shortname' forall a b. (a -> b) -> a -> b
$ String -> Sentence
S String
"Definition of Weight"

weightDeriv :: Derivation
weightDeriv :: Derivation
weightDeriv = Sentence -> [Sentence] -> Derivation
mkDerivName (forall n. NamedIdea n => n -> Sentence
phrase UnitalChunk
QP.weight) forall a b. (a -> b) -> a -> b
$ forall a. [[a]] -> [a]
weave [[Sentence]
weightDerivSentences, [Sentence]
weightDerivEqns]

weightDerivSentences, weightDerivEqns :: [Sentence]
weightDerivSentences :: [Sentence]
weightDerivSentences = forall a b. (a -> b) -> [a] -> [b]
map [Sentence] -> Sentence
foldlSentCol [[Sentence]
weightDerivAccelSentence, 
  [Sentence]
weightDerivNewtonSentence, [Sentence]
weightDerivReplaceMassSentence, 
  [Sentence]
weightDerivSpecWeightSentence]
weightDerivEqns :: [Sentence]
weightDerivEqns = forall a b. (a -> b) -> [a] -> [b]
map ModelExpr -> Sentence
eS [ModelExpr
weightDerivAccelEqn, ModelExpr
weightDerivNewtonEqn, 
  ModelExpr
weightDerivReplaceMassEqn, ModelExpr
weightDerivSpecWeightEqn]

weightDerivAccelSentence :: [Sentence]
weightDerivAccelSentence :: [Sentence]
weightDerivAccelSentence = [String -> Sentence
S String
"Under the influence" Sentence -> Sentence -> Sentence
`S.of_` forall n. NamedIdea n => n -> Sentence
phrase ConceptChunk
gravity Sentence -> Sentence -> Sentence
`sC` 
  String -> Sentence
S String
"and assuming a", forall c. Idea c => c -> Sentence
short CI
twoD, forall n. NamedIdea n => n -> Sentence
phrase ConceptChunk
cartesian, String -> Sentence
S String
"with down as positive" Sentence -> Sentence -> Sentence
`sC`
  String -> Sentence
S String
"an object has an", forall n. NamedIdea n => n -> Sentence
phrase UnitalChunk
QP.acceleration, forall n. NamedIdea n => n -> Sentence
phrase ConceptChunk
vector, String -> Sentence
S String
"of"]

weightDerivNewtonSentence :: [Sentence]
weightDerivNewtonSentence :: [Sentence]
weightDerivNewtonSentence = [String -> Sentence
S String
"Since there is only one non-zero", 
  forall n. NamedIdea n => n -> Sentence
phrase ConceptChunk
vector, forall n. NamedIdea n => n -> Sentence
phrase IdeaDict
component Sentence -> Sentence -> Sentence
`sC` String -> Sentence
S String
"the scalar", forall n. NamedIdea n => n -> Sentence
phrase IdeaDict
value, 
  forall c. (HasUID c, HasSymbol c) => c -> Sentence
ch UnitalChunk
QP.weight, String -> Sentence
S String
"will be used for the" Sentence -> Sentence -> Sentence
+:+. forall n. NamedIdea n => n -> Sentence
phrase UnitalChunk
QP.weight,
  String -> Sentence
S String
"In this scenario" Sentence -> Sentence -> Sentence
`sC` forall n. NamedIdea n => n -> Sentence
phrase TheoryModel
newtonSL, String -> Sentence
S String
"from", forall r.
(HasUID r, HasRefAddress r, HasShortName r) =>
r -> Sentence
refS TheoryModel
newtonSL, 
  String -> Sentence
S String
"can be expressed as"]

weightDerivReplaceMassSentence :: [Sentence]
weightDerivReplaceMassSentence :: [Sentence]
weightDerivReplaceMassSentence = [forall n. NamedIdea n => n -> Sentence
atStart UnitalChunk
QPP.mass, String -> Sentence
S String
"can be expressed as",
  forall n. NamedIdea n => n -> Sentence
phrase UnitalChunk
QPP.density, String -> Sentence
S String
"multiplied by", forall n. NamedIdea n => n -> Sentence
phrase UnitalChunk
QPP.vol Sentence -> Sentence -> Sentence
`sC` String -> Sentence
S String
"resulting in"]

weightDerivSpecWeightSentence :: [Sentence]
weightDerivSpecWeightSentence :: [Sentence]
weightDerivSpecWeightSentence = [String -> Sentence
S String
"Substituting", forall n. NamedIdea n => n -> Sentence
phrase UnitalChunk
QPP.specWeight, 
  String -> Sentence
S String
"as the product" Sentence -> Sentence -> Sentence
`S.of_` forall n. NamedIdea n => n -> Sentence
phrase UnitalChunk
QPP.density Sentence -> Sentence -> Sentence
`S.and_` forall n. NamedIdea n => n -> Sentence
phrase UnitalChunk
QP.gravitationalAccel,
  String -> Sentence
S String
"yields"]

-- * Pressure

hsPressureGD :: GenDefn
hsPressureGD :: GenDefn
hsPressureGD = forall u.
IsUnit u =>
ModelKind ModelExpr
-> Maybe u
-> Maybe Derivation
-> [DecRef]
-> String
-> [Sentence]
-> GenDefn
gd (forall e. QDefinition e -> ModelKind e
equationalModel' ModelQDef
hsPressureQD) (forall u. MayHaveUnit u => u -> Maybe UnitDefn
getUnit UnitalChunk
QP.pressure) forall a. Maybe a
Nothing
  [forall r.
(HasUID r, HasRefAddress r, HasShortName r) =>
r -> DecRef
dRef Reference
hsPressureSrc] String
"hsPressure" [Sentence
hsPressureNotes]

hsPressureQD :: ModelQDef
hsPressureQD :: ModelQDef
hsPressureQD = forall c e.
(Quantity c, MayHaveUnit c) =>
c -> NP -> e -> QDefinition e
mkQuantDef' UnitalChunk
QP.pressure (String -> NP
nounPhraseSP String
"hydrostatic pressure") forall r. ExprC r => r
hsPressureEqn

hsPressureSrc :: Reference
hsPressureSrc :: Reference
hsPressureSrc = String -> String -> ShortName -> Reference
makeURI String
"hsPressureSrc" String
"https://en.wikipedia.org/wiki/Pressure" forall a b. (a -> b) -> a -> b
$
  Sentence -> ShortName
shortname' forall a b. (a -> b) -> a -> b
$ String -> Sentence
S String
"Definition of Pressure"

hsPressureNotes :: Sentence
hsPressureNotes :: Sentence
hsPressureNotes = String -> Sentence
S String
"This" Sentence -> Sentence -> Sentence
+:+ forall n. NamedIdea n => n -> Sentence
phrase ConceptChunk
equation Sentence -> Sentence -> Sentence
+:+ String -> Sentence
S String
"is derived from" Sentence -> Sentence -> Sentence
+:+
  String -> Sentence
S String
"Bernoulli's" Sentence -> Sentence -> Sentence
+:+ forall n. NamedIdea n => n -> Sentence
phrase ConceptChunk
equation Sentence -> Sentence -> Sentence
+:+ String -> Sentence
S String
"for a slow moving fluid" Sentence -> Sentence -> Sentence
+:+
  String -> Sentence
S String
"through a porous" Sentence -> Sentence -> Sentence
+:+. forall n. NamedIdea n => n -> Sentence
phrase IdeaDict
material_

-- * Torque

torqueDD :: DataDefinition
torqueDD :: DataDefinition
torqueDD = SimpleQDef
-> Maybe Derivation -> String -> [Sentence] -> DataDefinition
ddENoRefs SimpleQDef
torque forall a. Maybe a
Nothing String
"torque" [Sentence
torqueDesc] 

torque :: SimpleQDef
torque :: SimpleQDef
torque = forall c e. (Quantity c, MayHaveUnit c) => c -> e -> QDefinition e
mkQuantDef UnitalChunk
QP.torque Expr
torqueEqn

torqueEqn :: Expr
torqueEqn :: Expr
torqueEqn = forall r c. (ExprC r, HasUID c, HasSymbol c) => c -> r
sy UnitalChunk
QP.positionVec forall r. ExprC r => r -> r -> r
`cross` forall r c. (ExprC r, HasUID c, HasSymbol c) => c -> r
sy UnitalChunk
QP.force

torqueDesc :: Sentence
torqueDesc :: Sentence
torqueDesc = [Sentence] -> Sentence
foldlSent [String -> Sentence
S String
"The", forall n. NamedIdea n => n -> Sentence
phrase SimpleQDef
torque, 
  String -> Sentence
S String
"on a body measures the", String -> Sentence
S String
"tendency" Sentence -> Sentence -> Sentence
`S.of_` String -> Sentence
S String
"a", forall n. NamedIdea n => n -> Sentence
phrase UnitalChunk
QP.force, 
  String -> Sentence
S String
"to rotate the body around an axis or pivot"]

-- * Vector Magnitude

vecMagQD :: SimpleQDef
vecMagQD :: SimpleQDef
vecMagQD = forall c e. (Quantity c, MayHaveUnit c) => c -> e -> QDefinition e
mkQuantDef UnitalChunk
QP.speed forall r. ExprC r => r
speedEqn

magNote :: Sentence
magNote :: Sentence
magNote = [Sentence] -> Sentence
foldlSent [String -> Sentence
S String
"For a given", forall n. NamedIdea n => n -> Sentence
phrase UnitalChunk
QP.velocity, String -> Sentence
S String
"vector", forall c. (HasUID c, HasSymbol c) => c -> Sentence
ch UnitalChunk
QP.velocity Sentence -> Sentence -> Sentence
`sC`
  String -> Sentence
S String
"the magnitude of the vector", Sentence -> Sentence
sParen (ModelExpr -> Sentence
eS forall r. ExprC r => r
speedEqn) Sentence -> Sentence -> Sentence
`S.isThe`
  String -> Sentence
S String
"scalar called", forall n. NamedIdea n => n -> Sentence
phrase UnitalChunk
QP.speed]

vecMag :: DataDefinition
vecMag :: DataDefinition
vecMag = SimpleQDef
-> Maybe Derivation -> String -> [Sentence] -> DataDefinition
ddENoRefs SimpleQDef
vecMagQD forall a. Maybe a
Nothing String
"vecMag" [Sentence
magNote]

-- * Newton's Second Law of Rotational Motion

newtonSLR :: TheoryModel
newtonSLR :: TheoryModel
newtonSLR = forall q c.
(Quantity q, MayHaveUnit q, Concept c) =>
ModelKind ModelExpr
-> [q]
-> [c]
-> [ModelQDef]
-> [ModelExpr]
-> [ModelQDef]
-> String
-> [Sentence]
-> TheoryModel
tmNoRefs (forall e. String -> QDefinition e -> ModelKind e
equationalModelU String
"newtonSLR" ModelQDef
newtonSLRQD)
  [forall q. (Quantity q, MayHaveUnit q) => q -> QuantityDict
qw UnitalChunk
QP.torque, forall q. (Quantity q, MayHaveUnit q) => q -> QuantityDict
qw UnitalChunk
QP.momentOfInertia, forall q. (Quantity q, MayHaveUnit q) => q -> QuantityDict
qw UnitalChunk
QP.angularAccel] 
  ([] :: [ConceptChunk]) [ModelQDef
newtonSLRQD] [] [] String
"NewtonSecLawRotMot" [Sentence]
newtonSLRNotes

newtonSLRQD :: ModelQDef
newtonSLRQD :: ModelQDef
newtonSLRQD = forall c e.
(Quantity c, MayHaveUnit c) =>
c -> NP -> e -> QDefinition e
mkQuantDef' UnitalChunk
QP.torque (String -> NP
nounPhraseSP String
"Newton's second law for rotational motion") forall r. ExprC r => r
newtonSLRExpr

newtonSLRExpr :: ExprC r => r
newtonSLRExpr :: forall r. ExprC r => r
newtonSLRExpr = forall r c. (ExprC r, HasUID c, HasSymbol c) => c -> r
sy UnitalChunk
QP.momentOfInertia forall r. ExprC r => r -> r -> r
`mulRe` forall r c. (ExprC r, HasUID c, HasSymbol c) => c -> r
sy UnitalChunk
QP.angularAccel

newtonSLRNotes :: [Sentence]
newtonSLRNotes :: [Sentence]
newtonSLRNotes = [[Sentence] -> Sentence
foldlSent
  [String -> Sentence
S String
"The net", forall a. Quantity a => a -> Sentence
getTandS UnitalChunk
QP.torque, String -> Sentence
S String
"on a", forall n. NamedIdea n => n -> Sentence
phrase ConceptChunk
rigidBody Sentence -> Sentence -> Sentence
`S.is`
   String -> Sentence
S String
"proportional to its", forall a. Quantity a => a -> Sentence
getTandS UnitalChunk
QP.angularAccel Sentence -> Sentence -> Sentence
`sC` String -> Sentence
S String
"where",
   forall c. (HasUID c, HasSymbol c) => c -> Sentence
ch UnitalChunk
QP.momentOfInertia, String -> Sentence
S String
"denotes", forall n. NamedIdea n => n -> Sentence
phrase UnitalChunk
QP.momentOfInertia Sentence -> Sentence -> Sentence
`S.the_ofThe`
   forall n. NamedIdea n => n -> Sentence
phrase ConceptChunk
rigidBody, String -> Sentence
S String
"as the", forall n. NamedIdea n => n -> Sentence
phrase IdeaDict
constant Sentence -> Sentence -> Sentence
`S.of_` String -> Sentence
S String
"proportionality"]]

-- * Acceleration

accelerationTM :: TheoryModel
accelerationTM :: TheoryModel
accelerationTM = forall q c.
(Quantity q, MayHaveUnit q, Concept c) =>
ModelKind ModelExpr
-> [q]
-> [c]
-> [ModelQDef]
-> [ModelExpr]
-> [ModelQDef]
-> [DecRef]
-> String
-> [Sentence]
-> TheoryModel
tm (forall e. String -> QDefinition e -> ModelKind e
equationalModelU String
"accelerationTM" ModelQDef
accelerationQD)
  [forall q. (Quantity q, MayHaveUnit q) => q -> QuantityDict
qw UnitalChunk
QP.acceleration, forall q. (Quantity q, MayHaveUnit q) => q -> QuantityDict
qw UnitalChunk
QP.velocity, forall q. (Quantity q, MayHaveUnit q) => q -> QuantityDict
qw UnitalChunk
QP.time] ([] :: [ConceptChunk]) [ModelQDef
accelerationQD] [] []
  [forall r.
(HasUID r, HasRefAddress r, HasShortName r) =>
r -> DecRef
dRef Citation
accelerationWiki] String
"acceleration" []

-- * Velocity

velocityTM :: TheoryModel
velocityTM :: TheoryModel
velocityTM = forall q c.
(Quantity q, MayHaveUnit q, Concept c) =>
ModelKind ModelExpr
-> [q]
-> [c]
-> [ModelQDef]
-> [ModelExpr]
-> [ModelQDef]
-> [DecRef]
-> String
-> [Sentence]
-> TheoryModel
tm (forall e. String -> QDefinition e -> ModelKind e
equationalModelU String
"velocityTM" ModelQDef
velocityQD)
  [forall q. (Quantity q, MayHaveUnit q) => q -> QuantityDict
qw UnitalChunk
QP.velocity, forall q. (Quantity q, MayHaveUnit q) => q -> QuantityDict
qw UnitalChunk
QP.position, forall q. (Quantity q, MayHaveUnit q) => q -> QuantityDict
qw UnitalChunk
QP.time] ([] :: [ConceptChunk]) [ModelQDef
velocityQD] [] []
  [forall r.
(HasUID r, HasRefAddress r, HasShortName r) =>
r -> DecRef
dRef Citation
velocityWiki] String
"velocity" []