Creating Your Project in Drasil - JacquesCarette/Drasil GitHub Wiki
Warning: Wiki should not be edited directly. Edit the files in the ./wiki/ folder instead and make a PR.
Contents
- Tips to Get Started
- Creating Your Project in Drasil
- Adding Sections to SRS Body
- Adding Introduction Section
- Adding Specific System Description (SSD) Section
- Adding Goal Statements Section
- Adding Assumptions Section
- Adding Theoretical Models Section
- Adding General Definitions Section
- Adding Data Definitions and Acronym Section
- Adding Instance Models Section
- Adding Constraints and Properties of a Correct Solution Section
- Adding Requirements Section
- Adding Non-Functional Requirements Section
- Adding Likely and Unlikely Changes
- Adding Other Sections
- Adding Traceability Section
- Notes
- Code Generation
Tips to Get Started
- You will be working mainly in the code folder.
- There are several sub-packages that you will require to create your software in Drasil.
- Many scientific theories, concepts, quantities and units commonly used in scientific problems are already coded in Drasil, you can reuse them as required. E.g Newton’s law of motion theory, units like meters, seconds, and so on. Drasil also contains concepts like gravitational acceleration, kinetic energy, velocity, and so on.
- You will be using branches and pull requests for your project. See the Contributor's Guide for more details
- In addition to this manual, you can use example projects as your cheat sheet to build your own project.
- Refer to the Haddock documentation for Drasil. A variant with fully exposed modules is also available.
- We would like to keep improving this user guide based on your feedback. Please create issue(s) on GitHub with what you think is missing, unclear, or should be included as you follow this guide. You can assign issues to @JacquesCarette or @smiths.
Getting Started:
- Follow the New Workspace Setup for setting up your machine for working with Drasil.
- For more information on the contents of a Software Requirements Specification (SRS), see Dr. Smith's template
- To create your project in Drasil, you will generally want to fork the repo and make your changes on your fork. Check out this pull request for more information on setting up your own bot for GitHub Actions.
- Setting up your workspace
Sub-packages in Drasil:
See Folder Layout for a more in-depth discussion. There are three sub-packages that you will primarily be working with:
drasil-gendefines the entry point for artifact generation.drasil-langcontains language primitives focused on mathematical knowledge capture. This package also includes a language for symbols (Symbol) and a language for mathematical expressions embedding symbols (Expr). It describes the layout of a document and much more.drasil-theorycontains chunk types for describing refinements of mathematical theories and instantiation of definitions.
There are several other sub-packages that you will need to work with on a smaller scale:
drasil-codeanddrasil-docLang: for generating code and documentation, respectively. You will mainly need them forChoicesandSRSDecl.drasil-databaseanddrasil-system: for gathering pieces of information and bundling them together.drasil-exampleanddrasil-website: good reference material if you need it.drasil-data: for knowing what things you can reuse (e.g. mathematical concepts and documentation concepts), and adding new things that others can reuse.
Creating Your Project in Drasil
Note: The instructions of this tutorial were last updated for a commit on 29 Oct 2022.
After all installation tasks and forking is completed and you are able to run existing example projects in Drasil, you are ready to create your own. You can use Visual Studio Code or any other editor that you are familiar with.
Adding a New User and Project Sub-Folder
-
If you are a new user, add your information
Peoples.hsincode/drasil-data/lib/Data/Drasil/People.hs. Create a new row and follow the same format to add your name, using the differentpersonfunctions as needed. -
Now, you will need to create a new sub-folder for your project. Navigate to
/code/drasil-example/and create your new folder. -
Make a copy of template folder into the new folder and rename the new folder to your project name. Make sure you give your project an intuitive name. For example, Double Pendulum can be represented as DblPendulum, Projectile is Projectile, Solar Water Heating System is SWHS, etc. (note – project name should be one word, no spaces).
-
Import module
Data.Drasil.PeopleintoBody.hs. This is the file where you added your name. This will be used to include your name as an author on your generated SRS document. E.g.import Data.Drasil.People (brenda) -
Decide a name for your software system and define it as a Common Idea (
CI) in a new file namedConcepts.hs. For example, gamePhysics would be represented with:
gamePhysics :: CI
gamePhysics = commonIdeaWithDict "gamePhysics" (pn "game physics library") "Game Physics" [physics]
For more information, please see the documentation for commonIdeaWithDict.
-
In
Body.hs, start constructing your chunk database (ChunkDB) in thesymbMapfunction by adding your program name (e.gnw “your software name”). Make sure the parameter you are adding here tallies with the value of the_sysrecord in defined insiinBody.hs.siholds all of your system's information as aSystemrecord type. -
Now you are ready to start constructing your SRS.
Create a Blank SRS Template for Your Project:
-
In your newly created project folder, open
Body.hs. Modify the file to reflect your project name by replacing all instances of the word 'Template' with your project name. You can perform a find and replace operation to complete this. -
Go to the
si(System) section of the code inBody.hsand populate the following fields with your own functions:
_sys = example --(will become the name of your software system e.g. dblpendulum)
_authors = [authorName] --(will become the same name you added to People.hs)
For reference, the si data is used to hold global information about a system.
si :: System
si = SI {
_sys = example,
_kind = Doc.srs,
_authors = [authorName],
_purpose = [],
_quants = [] :: [QuantityDict],
_concepts = [] :: [DefinedQuantityDict],
_instModels = [] :: [InstanceModel],
_datadefs = [] :: [DataDefinition],
_configFiles = [],
_inputs = [] :: [QuantityDict],
_outputs = [] :: [QuantityDict],
_defSequence = [] :: [Block QDefinition],
_constraints = [] :: [ConstrainedChunk],
_constants = [] :: [QDefinition],
_sysinfodb = symbMap,
_usedinfodb = usedDB,
refdb = refDB
}
- Remember to import your software system name from
Concepts.hsintoBody.hsas well as all other relevant modules. Once you have done this, you may totally remove theexampleandauthorNamefunctions fromBody.hs. There should be no need for these functions anymore as the second step renders them unneeded. If there are, just replace them with the ones you created.
Modifying Main.hs for Your Software
- Update your
Main.hsfile: Your main module will load all the other modules in your project to build and generate your SRS. - Open the
Main.hsfile in the current folder and replace all instances oftemplatewith your project name, save and close.
Update yaml and cabal Files
The package.yaml file contains some information about your project, including all the modules used in your project. From there, the compiler will generate a .cabal file for you. The information in the .cabal is then needed to actually build your project and connect all the packages included. As you add more modules to you project folder, you will need to update package.yaml (which will automatically update the .cabal file). You should almost never have to manually update the .cabal file.
- Navigate to
../code/drasil-example/**{your-new-example-folder}**/package.yaml - At the bottom, update the file using the other examples as a guide. It should look something like this:
...
library:
source-dirs: lib
when:
- condition: false
other-modules: Paths_{your-example-name}
executables:
yourExampleName:
main: Main
source-dirs: app
...
dependencies:
- {your-example-name}
when:
- condition: false
other-modules: Paths_{your-example-name}
Build Your Project – Run make
- Navigate to
code/Makefile, add your project to the list of other example projects and modify as applicable. - Navigate to the
codefolder from your terminal to build your project. - Run
maketo build your project. - Navigate to your project folder in
buildto view your output files. - When you build your project, any artifacts that Drasil was able to generate (e.g.
.texand.htmlversions of the SRS, executable code) will be auto-generated in appropriate sub-folders of the build folder. - After the build operation is completed, check the output of your SRS in the
.htmlfile. A cascading style sheet is also autogenerated in the same folder.
Updating Stable folder in code/stable/
You might have to update stable for all the other examples if you get the following error for any of the other examples. The one shown below is from the Template project:
-------------------------------------------
- logs/Template_log.log IS NOT EMPTY -- DIFFERENCE
- BETWEEN GENERATED AND STABLE OUTPUT FOUND
-------------------------------------------
-------------------------------------------
- ERROR IN GENERATED OUTPUT SEE ABOVE FOR -
- MORE DETAILS -
-------------------------------------------
Subsequently, you need to update stable for your new project whenever you make any changes. This can most easily be done by running make stabilize. Alternatively, you can follow these instructions manually:
- Make a copy of your project folder from
/Drasil/code/build/yourProjectName. - Paste in
Drasil/code/stableto create a folder for your project. Ensure that the version instablematches the version inbuildwhen pushing your project to your remote repository. - Rename your folder with the name you used for
_sysfrom thesivariable inBody.hs. This should be the same as what appeared in thebuildfolder. - Update
.htmland.texfiles (copy and replace) only. - When you build your project, and it says
GENERATED OUTPUT MATCHES STABLE VERSION, then stable is up to date, no need to update. Here is what a stabilized output will look like:
----------------------------
Make complete, checking logs
----------------------------
-------------------------------------------
- GENERATED OUTPUT MATCHES STABLE VERSION -
-------------------------------------------
GitHub Actions / Builds & Tests
If you'd like to test your new project against the existing build scripts, please include [workflow-trigger] in a commit message when pushing your work. This will force our Drasil build workflow to run on your branch, and you will be able to view logs of the run under the "Actions" tab. Alternatively, if you are working in a branch that already has a PR attached to it, it will automatically build and test without the [workflow-trigger] in your commit message. You may then view the logs related to your test run by finding the Action run linked to your commit/PR, or by visiting the "Actions" page and looking for your triggered test run.
For more information about our automated tests, please see our Workflow documentation.
Logging
A log file will be auto-generated in a logs folder for your project after every build: An example file path for this is: /code/logs/yourProjectName_log.log. The logs are generated by using diff between the build and stable folders to find any differences between the two folders.
Adding Sections to SRS Body
- After creating a blank SRS, you will be able to add sections to it and populate with information.
- The
Body.hsmodule of your project will be used to gather the sections of your SRS. - We will now begin to fill in the function
mkSRS. The value ofmkSRSwill include all the sections required in your SRS document. Visit the different examples for more information on this. A list of potential sections and their constructors can be found in the Haddock documentation. - You will find all the sections that can be created in
../code/drasil-docLang/lib/Drasil/DocLang/SRS.hs - Begin adding sections using the excerpt below:
mkSRS = [ TableOfContents -- Adds a Table of Contents section
RefSec $ -- Adds the reference material section
RefProg intro -- Add the introduction blob
[TUnits -- Adds table of units subsection
, tsymb [TSPurpose, TypogConvention [Vector Bold], SymbOrder, VectorUnits]
-- The above adds table of symbols with contents and specified rules e.g ordering content of table, bold vector symbols, adds purpose of document, etc.
, TAandA -- Adds table of abbreviation and acronym subsection
],
- Ensure that your import list contains DocLang's SRS:
import qualified Drasil.DocLang.SRS as SRS
-
At this point build your code (by running
make) and see what you generate. You should see the sections in step 5 displayed in your SRS. Depending on what you have added to mkSRS you may need to update the ChunkDB first, which will be explained below. -
The remainder of the tutorial will go over adding a subset of potential sections to your project. A complete list of potential sections can be found in the Haddock documentation. Not all sections need to be included in your project. See Dr. Smith's template for more information on each section.
Adding Introduction Section
You can add the ‘Introduction’ section and related sub-sections into Body.hs. The SRS section builder is defined in this module:
/code/drasil-docLang/lib/Drasil/DocLang/SRS.hs
Introduction constructors can be found in the IntroSec Haddock documentation.
- Start a new section in
mkSRSafter the block you created in step 5 above. - Add the introduction section information to your project. An example Introduction will look something like:
IntroSec $
IntroProg justification (phrase dblpendulum) -- This line introduces the system you want to build. 'justification' is a function that needs to be defined in `Body.hs` to hold the content of an introduction preamble.
[IScope scope], -- This line adds the Scope of Requirements section to SRS. You will need to define a constructor for scope in Body.hs with type 'Sentence'.
- Define a
scopeconstructor (example below). This will hold the content of the introduction preamble and must be aSentence.
scope :: Sentence
scope = foldlSent [S "dblpendulum is the subject" +:+. S "dblpendulum is the focus", phrase dblpendulum]
- Define a
justificationconstructor. It introduces the system you want to build.
justification :: Sentence
justification = foldlSent [ atStartNP (a_ pendulum), S "consists" `S.of_` phrase mass, ...]
- Other sub-sections similar to
scopein step 3 can also be included e.g.Purpose. Just make sure that you add to the imports andsymbMapas required. Here is a sample of the first few sections added for the Projectile project:
mkSRS :: SRSDecl
mkSRS = [
RefSec $
RefProg intro
[ TUnits
, tsymb [TSPurpose, TypogConvention [Vector Bold], SymbOrder, VectorUnits]
, TAandA
],
IntroSec $
IntroProg justification (phrase projectileTitle)
[ IScope scope ],
SSDSec $
SSDProg
[ SSDProblem $ PDProg prob []
[ TermsAndDefs Nothing terms
, PhySysDesc projectileTitle physSystParts figLaunch []
, Goals [(phrase iVel +:+ S "vector") `S.the_ofThe` phrase projectile]]
- Since we added a
scopesection, you will need to include the constructor name in the chunk database.scopeis defined in thedocconconstructor in../drasil-data/lib/Data/Drasil/Concepts/Documentation. The process of updating the chunk database may need to be repeated for other constructors that are created in other parts of the SRS.
doccon :: [NamedChunk]
doccon = [abbAcc, abbreviation, acronym, analysis, appendix, aspect, body,
caseProb, charOfIR, characteristic, class_, client, code, column, company,
component, concept, condition, connection, consVals, constant, constraint,
-- ...
safety, safetyReq, scenario, {-Here!-} scope, scpOfReq,
-- ...
validation, value, variable, vav, vavPlan, verification, video, year]
- In the 3rd argument of
symbMap, add thedocconanddoccon'functions. The third argument should now look like:
(nw yourSoftwarePackageName : [nw program] ++ map nw doccon ++ map nw doccon')
You must also import Data.Drasil.Concepts.Documentation as Doc (doccon, doccon') at the top of Body.hs.
symbMap maps references the the chunk database. Please review the GlassBR, NoPCM, and Projectile examples to understand how to populate it.
- You may choose to build your program every so often to keep track of errors easily.
Adding Goal Statements section
- Add a new subsection to
mkSRSafterPhySysDescso that the SSD section looks like this:
SSDSec $
SSDProg
[ SSDProblem $ PDProg prob []
[ TermsAndDefs Nothing terms
, PhySysDesc pendulumTitle physSystParts figMotion []
, Goals goalsInputs] -- This adds a goals section and goals input is defined for the preamble of the goal.
- The
goalsInputsfunction defines the preamble of your goal statement. You can definegoalsInputsinBody.hsor in a newGoals.hsfile. For this guide, we will use a newGoalsmodule. - Create a new module
Goals.hsin your working folder. - Define your goal statement using 'ConceptInstance' type.
- You will require the
goalStmtDomconcept fromData.Drasil.Concepts.Documentationto be added to your import list in yourGoals.hsmodule. You will use this function in defining your actual goal statement. YourGoals.hsfile should look something like this simplified excerpt from the Pendulum example:
module Drasil.DblPendulum.Goals (goals, goalsInputs, goalRefs) where
import Language.Drasil
import Data.Drasil.Concepts.Documentation (goalStmtDom)
goals :: [ConceptInstance]
goals = [motionMass]
goalsInputs :: [Sentence]
goalsInputs = [S "the mass and length of the rod, initial angle of the mass and the gravitational constant"]
motionMass :: ConceptInstance
motionMass = cic "motionMass"
(S "Calculate the motion of the mass")
"Motion-of-the-mass" goalStmtDom -- Here is where we apply goalStmtDom
- Add your module to the import list in
Body.hsto display your Goal statement section and updatesymbMapas required. - Add
goalsto yoursymbMapor toconcIns(which will be created in step 10 of the next section). - Add all other required parameters to your import list.
Adding Instance Models Section
Note: Instance Models are added with the Ims constructor under the SSDSolChSpec constructor in the Specific System Description section.
- Add the Instance Model section to
mkSRSfunction inBody.hs. It should look similar to this:
, TMs [] (Label : stdFields)
, GDs [] ([Label, Units] ++ stdFields) ShowDerivation
, DDs [] ([Label, Symbol, Units] ++ stdFields) ShowDerivation
, IMs [] ([Label, Input, Output, InConstraints, OutConstraints] ++ stdFields) ShowDerivation
- Create a new module
IMods.hs - In
symbMap, replace([] :: [InstanceModel])withiMods. - In IMods.hs, create a new function
iModswith type[InstanceModel]to declare your list of IM functions. E.g.
iMods :: [InstanceModel]
iMods = [iMod1, iMod2]
- Start defining your IM functions. See
/code/drasil-theory/lib/Theory/Drasil/InstanceModel.hsfor various constructors you can use in defining your instance model. Also see example projects or Haddock documentation for help. The arguments are used as follows:- Declare your IM constructor and the IM relational concept in the first argument.
- Define your input and output constraints in the next argument. Ensure that your input and output constraints are already declared or defined in your
Unitals.hsfile. - Your IMs should have derivations, declare the derivation function name and use it in the third argument.
- Declare a reference name for your IM function as a
Stringin the fourth argument - You can declare a list of functions for adding notes to your IM where applicable in the fifth argument.
Your instance model will look something like this excerpt from Pendulum:
angularDisplacementIM :: InstanceModel
angularDisplacementIM = imNoRefs (OthModel angularDisplacementRC)
[qwC lenRod $ UpFrom (Exc, exactDbl 0)
,qwC initialPendAngle $ UpFrom (Exc, exactDbl 0)
, qwC gravitationalAccel $ UpFrom (Exc, exactDbl 0)]
(qw pendDisplacementAngle) [UpFrom (Exc, exactDbl 0)]
(Just angularDisplacementDeriv) "calOfAngularDisplacement" [angularDispConstraintNote]
- Define your
RelationalConceptby defining the equation and a label for your IM. E.g
angularDisplacementRC :: RelationConcept
angularDisplacementRC = makeRC "angularDisplacementRC" (nounPhraseSP "calculation of angular displacement") -- Label goes here.
EmptyS $ apply1 pendDisplacementAngle time $= sy initialPendAngle `mulRe` cos ( sy angularFrequency `mulRe` sy time) -- Equation goes here.
- Define functions for your derivation, declared in the third argument of your instance model. You will need the weave function to combine derivation sentences and equations. See example projects for more details. Here is an excerpt from Pendulum for the top-level
angularDisplacementDerivfunction (which is used inangularDisplacementTMas shown above):
angularDisplacementDeriv :: Derivation
angularDisplacementDeriv = mkDerivName (phrase angularDisplacement) (weave [angularDisplacementDerivSents, map eS angularDisplacementDerivEqns])
angularDisplacementDerivSents :: [Sentence]
angularDisplacementDerivSents = [angularDisplacementDerivSent1, angularDisplacementDerivSent2, angularDisplacementDerivSent3,
angularDisplacementDerivSent4, angularDisplacementDerivSent5]
- Define separate functions for your derivation sentences and equations.
- Define functions for notes where applicable, as declared in the fifth argument of your instance model. E.g.
angularDispConstraintNote :: Sentence
angularDispConstraintNote = foldlSent [atStartNP (the constraint),
eS (sy initialPendAngle $> exactDbl 0) `S.is` (S "required" !.),
atStartNP (the angularFrequency) `S.is` definedIn'' angFrequencyGD]
- Add all the required imports.
- Update
symbolsfunction inUnitals.hswhere applicable. - Update the chunk database (
symbMap) as applicable.
Adding Requirements Section
- Declare the requirements section in
mkSRS(inBody.hs):
ReqrmntSec $ ReqsProg
[ FReqsSub EmptyS []
- Create a
Requirements.hsmodule. - Define a list function to declare all your functional requirements. See example in the code excerpt under step 5.
- Define your requirement functions. You will need to tag every functional requirement with
funcReqDomas shown below:
funcReqs :: [ConceptInstance]
funcReqs = [verifyInptVals, calcAngPos, outputValues]
verifyInptVals, calcAngPos, outputValues :: ConceptInstance
verifyInptVals = cic "verifyInptVals" verifyInptValsDesc "Verify-Input-Values" funcReqDom
calcAngPos = cic "calcAngPos" calcAngPosDesc "Calculate-Angular-Position-Of-Mass" funcReqDom
outputValues = cic "outputValues" outputValuesDesc "Output-Values" funcReqDom
verifyInptValsDesc, calcAngPosDesc, outputValuesDesc :: Sentence
- Define the descriptions (as
Sentences) for your functional requirements. - Add
funcReqstoconcInsinBody.hs.
concIns :: [ConceptInstance]
concIns = assumptions ++ goals ++ funcReqs
- Add all necessary modules and parameters to the list of imports.
Adding Other Sections
Please review GamePhysics' Body.hs to see an example of this section.
- You can add other sections not included explicitly in this manual into your SRS body. For example, to add an "Off the Shelf Solution" section use:
UCsSec,
OffShelfSonsSec $ OffShelfSolnsProg offShelfSols,
For more information regarding the different possible sections, please visit the Haddock documentation for document language.
Notes
- Ensure that all the units used in your project are added to unit map in
symbMapfunction. The chunk database needs to know this information to print the SRS. - Helper function to build unitals are found here:
Drasil-lang/language/Drasil/chunk/Unitals.hs - Remember to create functions in
Unitals.hsto store your input and output parameters. - If you have used any references, remember to below code into
Body.hsto display your references:
refDB :: ReferenceDB
refDB = rdb citations concIns
- Reminder to add
acronymnsandsymbolstousedDBchunk database to display your acronymns and symbols tables:
usedDB :: ChunkDB
usedDB = cdb ([] :: [QuantityDict]) (map nw acronymn ++ map nw symbols) ([] :: [ConceptChunk])([] :: [UnitDefn]) [] [] [] [] [] [] []
- Your
mkSRSandsifunctions should now look something like this example from Projectile:
mkSRS :: SRSDecl
mkSRS = [
RefSec $
RefProg intro
[ TUnits
, tsymb [TSPurpose, TypogConvention [Vector Bold], SymbOrder, VectorUnits]
, TAandA
],
IntroSec $
IntroProg justification (phrase projectileTitle)
[ IScope scope ],
SSDSec $
SSDProg
[ SSDProblem $ PDProg prob []
[ TermsAndDefs Nothing terms
, PhySysDesc projectileTitle physSystParts figLaunch []
, Goals [(phrase iVel +:+ S "vector") `S.the_ofThe` phrase projectile]]
, SSDSolChSpec $ SCSProg
[ Assumptions
, TMs [] (Label : stdFields)
, GDs [] ([Label, Units] ++ stdFields) ShowDerivation
, DDs [] ([Label, Symbol, Units] ++ stdFields) ShowDerivation
, IMs [] ([Label, Input, Output, InConstraints, OutConstraints] ++ stdFields) ShowDerivation
, Constraints EmptyS inConstraints
, CorrSolnPpties outConstraints []
]
],
ReqrmntSec $
ReqsProg
[ FReqsSub EmptyS []
, NonFReqsSub
],
TraceabilitySec $ TraceabilityProg $ traceMatStandard si,
AuxConstntSec $
AuxConsProg projectileTitle constants,
Bibliography
]
si :: System
si = SI {
_sys = projectileTitle,
_kind = Doc.srs,
_authors = [samCrawford, brooks, spencerSmith],
_purpose = [],
_quants = symbols,
_concepts = [] :: [DefinedQuantityDict],
_instModels = iMods,
_datadefs = dataDefs,
_configFiles = [],
_inputs = inputs,
_outputs = outputs,
_defSequence = [] :: [Block QDefinition],
_constraints = map cnstrw constrained,
_constants = constants,
_sysinfodb = symbMap,
_usedinfodb = usedDB,
refdb = refDB
}
Code Generation
- Please refer to
NoPCMorGlassBRto generate code for your project from Drasil. - The
NoPCMexample can be referred to, if your project requires an ODE, otherwise, you can refer to theGlassBRexample. - Before you generate your code, ensure your
Systemstructure is correct, particularly the inputs, outputs, relations, and constraints should be filled in and correct. - The Drasil code generator requires that you set design variabilities for your code. An overview of design variabilities can be found in Chapter 8 of this document.
Modify Main.hs
- Navigate to
code/drasil-example/yourProjectName. Then, mirror theMain.hsfile from eitherGlassBRorNoPCM. Also create a newChoices.hsfile and mirror that fromGlassBRorNoPCM. The newChoices.hsfile will let you augment your generated code depending on the choices you make. - Copy the content of the
Main.hsfile and paste in yourMain.hsproject file. Keep in mind there are some elements in the file that you already have in you yourMain.hsfile, so carefully delete duplicated or unwanted texts and modify the other content to suit your project. - Begin by modifying your design choices: see Chapter 8 of this document for more information.
- Update your import list as required in
Choices.hs:
import Language.Drasil.Code (Choices(..), CodeSpec, codeSpec, Comments(..),
Verbosity(..), ConstraintBehaviour(..), ImplementationType(..), Lang(..),
Modularity(..), Structure(..), ConstantStructure(..), ConstantRepr(..),
InputModule(..), AuxFile(..), Visibility(..), defaultChoices)
- Implement the functions created from
Choices.hsintoMain.hs.GlassBRis a great example to figure out where these functions go. - Update the
Makefilein thecodefolder. - You may need to use some of the following functions, so add some or all of these imports to
Body.hsorChoices.hsas applicable:
import Language.Drasil.Code (relToQD, quantvar, listToArray)
import Data.Drasil.ExternalLibraries.ODELibraries (scipyODESymbols, osloSymbols,
arrayVecDepVar, apacheODESymbols, odeintSymbols)
import Database.Drasil (Block(Parallel), ChunkDB, ReferenceDB,
System(SI), cdb, rdb, refdb, _authors, _purpose, _concepts,
_constants, _constraints, _datadefs, _instModels, _configFiles, _defSequence,
_inputs, _kind, _outputs, _quants, _sys, _sysinfodb, _usedinfodb)
- Run
make. - Your build folder should now contain a
srcfolder.