{-# LANGUAGE PostfixOperators #-}
module Drasil.GamePhysics.GenDefs (generalDefns, accelGravityGD, impulseGD) where

import Language.Drasil
import qualified Language.Drasil.Sentence.Combinators as S
import Theory.Drasil (GenDefn, gd, equationalModel')
import Utils.Drasil (weave)
import qualified Data.Drasil.Quantities.Physics as QP (acceleration,
 gravitationalAccel, gravitationalConst, restitutionCoef, impulseS, force,
 fOfGravity)
import Drasil.GamePhysics.Unitals (mLarger, dispNorm, dVect, massA, massB,
  momtInertA, momtInertB, normalLen, normalVect, perpLenA, perpLenB, initRelVel,
  mass_1, mass_2, sqrDist, distMass)
import Drasil.GamePhysics.DataDefs (collisionAssump, rightHandAssump,
  rigidTwoDAssump)
import Data.Drasil.Concepts.Math as CM (line, cartesian)
import qualified Data.Drasil.Quantities.PhysicalProperties as QPP (mass)
import Drasil.GamePhysics.TMods (newtonLUG)

----- General Models -----

generalDefns :: [GenDefn]
generalDefns :: [GenDefn]
generalDefns = [GenDefn
accelGravityGD, GenDefn
impulseGD]


{-conservationOfMomentGDef :: RelationConcept
conservationOfMomentGDef = makeRC "conservOfMoment" (nounPhraseSP "Conservation of Momentum") 
  conservationOfMomentDesc conservationOfMomentRel

conservationOfMomentRel :: Relation
conservationOfMomentRel = UnaryOp $ Summation Nothing
  C massI

conservationOfMomentDesc :: Sentence
conservationOfMomentDesc = foldlSent [S "In an isolated system,",
  S "where the sum of external", phrase impulseS, S "acting on the system is zero,",
  S "the total momentum of the bodies is constant (conserved)"
  ]

--[mass, initialVelocity, finalVelocity]

conservationOfMomentDeriv :: Sentence
conservationOfMomentDeriv = foldlSent [S "When bodies collide, they exert",
  S "an equal (force) on each other in opposite directions" +:+.
  S "This is Newton's third law:",
  S "(expr1)",
  S "The objects collide with each other for the exact same amount of", 
  phrase time, getS time,
  S "The above equation is equal to the", phrase impulseS, 
  S "(GD1 ref)",
  S "(expr2)",
  S "The", phrase impulseS, S "is equal to the change in momentum:",
  S "(expr3)",
  S "Substituting 2*ref to 2* into 1*ref to 1* yields:",
  S "(expr4)",
  S "Expanding and rearranging the above formula gives",
  S "(expr5)",
  S "Generalizing for multiple (k) colliding objects:",
  S "(expr6)"
  ]
-}

--------------------------Acceleration due to gravity----------------------------
accelGravityGD :: GenDefn
accelGravityGD :: GenDefn
accelGravityGD = forall u.
IsUnit u =>
ModelKind ModelExpr
-> Maybe u
-> Maybe Derivation
-> [DecRef]
-> String
-> [Sentence]
-> GenDefn
gd (forall e. QDefinition e -> ModelKind e
equationalModel' ModelQDef
accelGravityQD) (forall u. MayHaveUnit u => u -> Maybe UnitDefn
getUnit UnitalChunk
QP.acceleration) (forall a. a -> Maybe a
Just Derivation
accelGravityDeriv)
   [forall r.
(HasUID r, HasRefAddress r, HasShortName r) =>
r -> DecRef
dRef Reference
accelGravitySrc] String
"accelGravity" [Sentence
accelGravityDesc]

accelGravityQD :: ModelQDef
accelGravityQD :: ModelQDef
accelGravityQD = forall c e.
(Quantity c, MayHaveUnit c) =>
c -> NP -> e -> QDefinition e
mkQuantDef' UnitalChunk
QP.gravitationalAccel (String -> NP
nounPhraseSP String
"Acceleration due to gravity") PExpr
accelGravityExpr

accelGravityDesc :: Sentence
accelGravityDesc :: Sentence
accelGravityDesc = [Sentence] -> Sentence
foldlSent [String -> Sentence
S String
"If one of the", forall n. NamedIdea n => n -> Sentence
plural UnitalChunk
QPP.mass, String -> Sentence
S String
"is much larger than the other" Sentence -> Sentence -> Sentence
`sC`
  (String -> Sentence
S String
"it is convenient to define a gravitational field around the larger mass as shown above" !.),
  String -> Sentence
S String
"The negative sign in the equation indicates that the", forall n. NamedIdea n => n -> Sentence
phrase UnitalChunk
QP.force, String -> Sentence
S String
"is an attractive",
  forall n. NamedIdea n => n -> Sentence
phrase UnitalChunk
QP.force]

accelGravityExpr :: PExpr
accelGravityExpr :: PExpr
accelGravityExpr = forall r. ExprC r => r -> r
neg ((forall r c. (ExprC r, HasUID c, HasSymbol c) => c -> r
sy UnitalChunk
QP.gravitationalConst forall r. ExprC r => r -> r -> r
`mulRe` forall r c. (ExprC r, HasUID c, HasSymbol c) => c -> r
sy UnitalChunk
mLarger forall r. ExprC r => r -> r -> r
$/
  forall r. (ExprC r, LiteralC r) => r -> r
square (forall r c. (ExprC r, HasUID c, HasSymbol c) => c -> r
sy UnitalChunk
dispNorm)) forall r. ExprC r => r -> r -> r
`mulRe` forall r c. (ExprC r, HasUID c, HasSymbol c) => c -> r
sy UnitalChunk
dVect)

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

accelGravityDeriv :: Derivation
accelGravityDeriv :: Derivation
accelGravityDeriv = Sentence -> [Sentence] -> Derivation
mkDerivName (forall n. NamedIdea n => n -> Sentence
phrase UnitalChunk
QP.gravitationalAccel)
                      (forall a. [[a]] -> [a]
weave [[Sentence]
accelGravityDerivSentences, forall a b. (a -> b) -> [a] -> [b]
map ModelExpr -> Sentence
eS forall r. (ExprC r, LiteralC r) => [r]
accelGravityDerivEqns])

accelGravityDerivSentences :: [Sentence]
accelGravityDerivSentences :: [Sentence]
accelGravityDerivSentences = forall a b. (a -> b) -> [a] -> [b]
map [Sentence] -> Sentence
foldlSentCol [[Sentence]
accelGravityDerivSentence1,
 [Sentence]
accelGravityDerivSentence2, [Sentence]
accelGravityDerivSentence3, [Sentence]
accelGravityDerivSentence4,
 [Sentence]
accelGravityDerivSentence5]

accelGravityDerivSentence1 :: [Sentence]
accelGravityDerivSentence1 :: [Sentence]
accelGravityDerivSentence1 = [String -> Sentence
S String
"From", forall r.
(HasUID r, HasRefAddress r, HasShortName r) =>
r -> Sentence -> Sentence
namedRef TheoryModel
newtonLUG (String -> Sentence
S String
"Newton's law of universal gravitation") Sentence -> Sentence -> Sentence
`sC` String -> Sentence
S String
"we have"]


accelGravityDerivSentence2 :: [Sentence]
accelGravityDerivSentence2 :: [Sentence]
accelGravityDerivSentence2 = [(String -> Sentence
S String
"The above equation governs the gravitational attraction between two bodies" !.),
        String -> Sentence
S String
"Suppose that one of the bodies is significantly more massive than the other" Sentence -> Sentence -> Sentence
`sC`
        String -> Sentence
S String
"so that we concern ourselves with the", forall n. NamedIdea n => n -> Sentence
phrase UnitalChunk
QP.force,
        String -> Sentence
S String
"the massive body",
        (String -> Sentence
S String
"exerts on the lighter body" !.), String -> Sentence
S String
"Further" Sentence -> Sentence -> Sentence
`sC` String -> Sentence
S String
"suppose that the", forall n. NamedIdea n => n -> Sentence
phrase ConceptChunk
cartesian Sentence -> Sentence -> Sentence
`S.is`
        String -> Sentence
S String
"chosen such that this", forall n. NamedIdea n => n -> Sentence
phrase UnitalChunk
QP.force, String -> Sentence
S String
"acts on a", forall n. NamedIdea n => n -> Sentence
phrase ConceptChunk
line,
        (String -> Sentence
S String
"which lies along one of the principal axes" !.),
        String -> Sentence
S String
"Then our", forall a. Quantity a => a -> Sentence
getTandS UnitalChunk
dVect, String -> Sentence
S String
"for the x or y axes is"]

accelGravityDerivSentence3 :: [Sentence]
accelGravityDerivSentence3 :: [Sentence]
accelGravityDerivSentence3 =  [String -> Sentence
S String
"Given the above assumptions" Sentence -> Sentence -> Sentence
`sC` String -> Sentence
S String
"let", forall c. (HasUID c, HasSymbol c) => c -> Sentence
ch UnitalChunk
mLarger Sentence -> Sentence -> Sentence
`S.and_` forall c. (HasUID c, HasSymbol c) => c -> Sentence
ch UnitalChunk
QPP.mass,
        String -> Sentence
S String
"be", forall n. NamedIdea n => n -> Sentence
phrase UnitalChunk
QPP.mass Sentence -> Sentence -> Sentence
`S.the_ofThe` (String -> Sentence
S String
"massive and light body respectively" !.),
        String -> Sentence
S String
"Equating", forall c. (HasUID c, HasSymbol c) => c -> Sentence
ch UnitalChunk
QP.force, String -> Sentence
S String
"above with Newton's second law",
        String -> Sentence
S String
"for the", forall n. NamedIdea n => n -> Sentence
phrase UnitalChunk
QP.force, String -> Sentence
S String
"experienced by the light body" Sentence -> Sentence -> Sentence
`sC` String -> Sentence
S String
"we get"]

accelGravityDerivSentence4 :: [Sentence]
accelGravityDerivSentence4 :: [Sentence]
accelGravityDerivSentence4 =  [String -> Sentence
S String
"where", (forall c. (HasUID c, HasSymbol c) => c -> Sentence
ch UnitalChunk
QP.gravitationalAccel Sentence -> Sentence -> Sentence
`S.isThe` forall n. NamedIdea n => n -> Sentence
phrase UnitalChunk
QP.gravitationalAccel !.),
        String -> Sentence
S String
"Dividing the above equation by", forall c. (HasUID c, HasSymbol c) => c -> Sentence
ch UnitalChunk
QPP.mass Sentence -> Sentence -> Sentence
`sC` String -> Sentence
S String
" we have"]

accelGravityDerivSentence5 :: [Sentence]
accelGravityDerivSentence5 :: [Sentence]
accelGravityDerivSentence5 =  [String -> Sentence
S String
"and thus the negative sign indicates that the", forall n. NamedIdea n => n -> Sentence
phrase UnitalChunk
QP.force Sentence -> Sentence -> Sentence
`S.is`
                               String -> Sentence
S String
"an attractive", forall n. NamedIdea n => n -> Sentence
phrase UnitalChunk
QP.force]

accelGravityDerivEqn1 :: PExpr
accelGravityDerivEqn1 :: PExpr
accelGravityDerivEqn1 = forall r c. (ExprC r, HasUID c, HasSymbol c) => c -> r
sy UnitalChunk
QP.force forall r. ExprC r => r -> r -> r
$= (forall r c. (ExprC r, HasUID c, HasSymbol c) => c -> r
sy UnitalChunk
QP.gravitationalConst forall r. ExprC r => r -> r -> r
`mulRe` (forall r c. (ExprC r, HasUID c, HasSymbol c) => c -> r
sy UnitalChunk
mass_1 forall r. ExprC r => r -> r -> r
`mulRe` forall r c. (ExprC r, HasUID c, HasSymbol c) => c -> r
sy UnitalChunk
mass_2) forall r. ExprC r => r -> r -> r
$/
                        forall r c. (ExprC r, HasUID c, HasSymbol c) => c -> r
sy UnitalChunk
sqrDist) forall r. ExprC r => r -> r -> r
`mulRe` forall r c. (ExprC r, HasUID c, HasSymbol c) => c -> r
sy UnitalChunk
dVect

accelGravityDerivEqn2 :: PExpr
accelGravityDerivEqn2 :: PExpr
accelGravityDerivEqn2 = forall r c. (ExprC r, HasUID c, HasSymbol c) => c -> r
sy UnitalChunk
dVect forall r. ExprC r => r -> r -> r
$= (forall r c. (ExprC r, HasUID c, HasSymbol c) => c -> r
sy UnitalChunk
distMass forall r. ExprC r => r -> r -> r
$/ forall r c. (ExprC r, HasUID c, HasSymbol c) => c -> r
sy UnitalChunk
dispNorm)

accelGravityDerivEqn3 :: PExpr
accelGravityDerivEqn3 :: PExpr
accelGravityDerivEqn3 = forall r c. (ExprC r, HasUID c, HasSymbol c) => c -> r
sy UnitalChunk
QP.fOfGravity forall r. ExprC r => r -> r -> r
$= forall r c. (ExprC r, HasUID c, HasSymbol c) => c -> r
sy UnitalChunk
QP.gravitationalConst forall r. ExprC r => r -> r -> r
`mulRe`
                         (forall r c. (ExprC r, HasUID c, HasSymbol c) => c -> r
sy UnitalChunk
mLarger forall r. ExprC r => r -> r -> r
`mulRe` forall r c. (ExprC r, HasUID c, HasSymbol c) => c -> r
sy UnitalChunk
QPP.mass forall r. ExprC r => r -> r -> r
$/ forall r c. (ExprC r, HasUID c, HasSymbol c) => c -> r
sy UnitalChunk
sqrDist) forall r. ExprC r => r -> r -> r
`mulRe` forall r c. (ExprC r, HasUID c, HasSymbol c) => c -> r
sy UnitalChunk
dVect
                         forall r. ExprC r => r -> r -> r
$= forall r c. (ExprC r, HasUID c, HasSymbol c) => c -> r
sy UnitalChunk
QPP.mass forall r. ExprC r => r -> r -> r
`mulRe` forall r c. (ExprC r, HasUID c, HasSymbol c) => c -> r
sy UnitalChunk
QP.gravitationalAccel

accelGravityDerivEqn4 :: PExpr
accelGravityDerivEqn4 :: PExpr
accelGravityDerivEqn4 = forall r c. (ExprC r, HasUID c, HasSymbol c) => c -> r
sy UnitalChunk
QP.gravitationalConst forall r. ExprC r => r -> r -> r
`mulRe`  (forall r c. (ExprC r, HasUID c, HasSymbol c) => c -> r
sy UnitalChunk
mLarger forall r. ExprC r => r -> r -> r
$/ forall r c. (ExprC r, HasUID c, HasSymbol c) => c -> r
sy UnitalChunk
sqrDist) forall r. ExprC r => r -> r -> r
`mulRe` forall r c. (ExprC r, HasUID c, HasSymbol c) => c -> r
sy UnitalChunk
dVect forall r. ExprC r => r -> r -> r
$= forall r c. (ExprC r, HasUID c, HasSymbol c) => c -> r
sy UnitalChunk
QP.gravitationalAccel

accelGravityDerivEqn5 :: PExpr
accelGravityDerivEqn5 :: PExpr
accelGravityDerivEqn5 = forall r c. (ExprC r, HasUID c, HasSymbol c) => c -> r
sy UnitalChunk
QP.gravitationalAccel forall r. ExprC r => r -> r -> r
$= forall r. ExprC r => r -> r
neg (forall r c. (ExprC r, HasUID c, HasSymbol c) => c -> r
sy UnitalChunk
QP.gravitationalConst forall r. ExprC r => r -> r -> r
`mulRe`  (forall r c. (ExprC r, HasUID c, HasSymbol c) => c -> r
sy UnitalChunk
mLarger forall r. ExprC r => r -> r -> r
$/ forall r c. (ExprC r, HasUID c, HasSymbol c) => c -> r
sy UnitalChunk
sqrDist)) forall r. ExprC r => r -> r -> r
`mulRe` forall r c. (ExprC r, HasUID c, HasSymbol c) => c -> r
sy UnitalChunk
dVect

accelGravityDerivEqns :: (ExprC r, LiteralC r) => [r]
accelGravityDerivEqns :: forall r. (ExprC r, LiteralC r) => [r]
accelGravityDerivEqns = [PExpr
accelGravityDerivEqn1, PExpr
accelGravityDerivEqn2, PExpr
accelGravityDerivEqn3,
                         PExpr
accelGravityDerivEqn4, PExpr
accelGravityDerivEqn5]



----------------------------Impulse for Collision--------------------------------------------

impulseGD :: GenDefn
impulseGD :: GenDefn
impulseGD = forall u.
IsUnit u =>
ModelKind ModelExpr
-> Maybe u
-> Maybe Derivation
-> [DecRef]
-> String
-> [Sentence]
-> GenDefn
gd (forall e. QDefinition e -> ModelKind e
equationalModel' ModelQDef
impulseQD) (forall u. MayHaveUnit u => u -> Maybe UnitDefn
getUnit UnitalChunk
QP.impulseS) forall a. Maybe a
Nothing
  [forall r.
(HasUID r, HasRefAddress r, HasShortName r) =>
r -> DecRef
dRef Reference
impulseSrc] String
"impulse" [Sentence
rigidTwoDAssump, Sentence
rightHandAssump, Sentence
collisionAssump]

impulseQD :: ModelQDef
impulseQD :: ModelQDef
impulseQD = forall c e.
(Quantity c, MayHaveUnit c) =>
c -> NP -> e -> QDefinition e
mkQuantDef' UnitalChunk
QP.impulseS (String -> NP
nounPhraseSP String
"Impulse for Collision") PExpr
impulseExpr

impulseExpr :: PExpr
impulseExpr :: PExpr
impulseExpr = (forall r. ExprC r => r -> r
neg (forall r. LiteralC r => Integer -> r
exactDbl Integer
1 forall r. ExprC r => r -> r -> r
`addRe` forall r c. (ExprC r, HasUID c, HasSymbol c) => c -> r
sy DefinedQuantityDict
QP.restitutionCoef) forall r. ExprC r => r -> r -> r
`mulRe` forall r c. (ExprC r, HasUID c, HasSymbol c) => c -> r
sy UnitalChunk
initRelVel forall r. ExprC r => r -> r -> r
$.
  forall r c. (ExprC r, HasUID c, HasSymbol c) => c -> r
sy UnitalChunk
normalVect) forall r. ExprC r => r -> r -> r
$/ ((forall r. (ExprC r, LiteralC r) => r -> r
recip_ (forall r c. (ExprC r, HasUID c, HasSymbol c) => c -> r
sy UnitalChunk
massA) forall r. ExprC r => r -> r -> r
`addRe` forall r. (ExprC r, LiteralC r) => r -> r
recip_ (forall r c. (ExprC r, HasUID c, HasSymbol c) => c -> r
sy UnitalChunk
massB)) forall r. ExprC r => r -> r -> r
`mulRe`
  forall r. (ExprC r, LiteralC r) => r -> r
square (forall r c. (ExprC r, HasUID c, HasSymbol c) => c -> r
sy UnitalChunk
normalLen) forall r. ExprC r => r -> r -> r
`addRe`
  (forall r. (ExprC r, LiteralC r) => r -> r
square (forall r c. (ExprC r, HasUID c, HasSymbol c) => c -> r
sy UnitalChunk
perpLenA) forall r. ExprC r => r -> r -> r
$/ forall r c. (ExprC r, HasUID c, HasSymbol c) => c -> r
sy UnitalChunk
momtInertA) forall r. ExprC r => r -> r -> r
`addRe`
  (forall r. (ExprC r, LiteralC r) => r -> r
square (forall r c. (ExprC r, HasUID c, HasSymbol c) => c -> r
sy UnitalChunk
perpLenB) forall r. ExprC r => r -> r -> r
$/ forall r c. (ExprC r, HasUID c, HasSymbol c) => c -> r
sy UnitalChunk
momtInertB))

impulseSrc :: Reference
impulseSrc :: Reference
impulseSrc = String -> String -> ShortName -> Reference
makeURI String
"impulseSrc" String
"http://www.chrishecker.com/images/e/e7/Gdmphys3.pdf" forall a b. (a -> b) -> a -> b
$
  Sentence -> ShortName
shortname' forall a b. (a -> b) -> a -> b
$ String -> Sentence
S String
"Impulse for Collision Ref"