The skeleton as a sequence of constructs
A container spells a skeleton as a sequence of constructs: description blocks, path blocks, component directives, declarations, equations (model, initialization and constraint) and reactions. This is the container-independent middle layer:
itemslists the constructs of a skeleton in the printer’s order;unitemsreads a construct sequence back into a skeleton. A construct belongs to the section of the last component directive before it, or to the document when there is none; within a section, constructs may come in any order (a document can interleave declarations and equations with its prose), except that the math entries of one field keep their order.unitems_itemsis the round trip.
Math entries are held as the container’s math text (Doc MR) at this layer; rawDoc
prints them under each component’s symbol table and cookDoc
reads them back
(cookDoc_rawDoc
), the symbol table coming from the rest of the skeleton
(symFor_mapMath), so both sides use the same table.
inductive RItem where
| desc (s : String)
| block (k : String) (v : Json)
| comp (K : Kind) (name : String)
| decl (d : Decl)
| eqn (raw : String)
| eqx (r : Role) (raw : String)
| rxn (x : Rxn String)
| plot (attrs : List (String × Json))
| tm (t : Tm String)
One construct of a document. An equation is its math text, uninterpreted; so is a
reaction’s rate. eqn is a model equation, eqx an equation of the field of its role
(the containers write it for initialization equations and constraints).
def items (D : Doc MR) : List RItem
The constructs of a skeleton, in the printer’s order: the document description, the top-level blocks, the top-level templates, then each component section.
Reading constructs back
def addTo (c : Comp MR) : RItem → Option (Comp MR)
Add a construct to a component section. A second description is refused (and a math field written twice is refused when the section is rebuilt).
structure St where
desc : Option String
blocks : List (String × Json)
math : List MR
comps : List (Comp MR)
cur : Option (Comp MR)
The reader’s state: the document description, blocks and templates, the finished sections, and the open one.
def step (st : St) : RItem → Option St
Read one construct. Before the first directive only a description, blocks and templates are allowed.
def unitems (front : List (String × Json)) (its : List RItem) : Option (Doc MR)
Read a construct sequence (with the front matter) into a skeleton.
The round trip
def itemsOK (D : Doc MR) : Prop
A skeleton the constructs can carry: a component’s blocks are not keyed by a math field, and its math blocks are (the parser files a block by its key); the top-level entries are templates.
theorem unitems_items (D : Doc MR) (hD : itemsOK D) : unitems D.front (items D) = some D
The construct round trip.
Math entries: printed under the symbol table, and read back
def rawDoc (pr : Sym → MC → MR) (D : Doc MC) : Doc MR
Print every math entry under its symbol table: a top-level template under the document’s, a component’s entry under the component’s.
def cookComp (ck : Sym → MR → Option (List MC)) (D : Doc MR) (c : Comp MR) : Option (Comp MC)
Read a component’s math entries under its symbol table; one math text may hold several equations (the multi-line variants).
def cookDoc (ck : Sym → MR → Option (List MC)) (D : Doc MR) : Option (Doc MC)
Read every math entry of a skeleton.
theorem topSym_rawDoc (pr : Sym → MC → MR) (hpr : ∀ S, HeadsKept (pr S)) (D : Doc MC) :
topSym (rawDoc pr D) = topSym D
The tables of a printed skeleton are those of the skeleton: the printer keeps every header.
theorem cookDoc_rawDoc (pr : Sym → MC → MR) (ck : Sym → MR → Option (List MC))
(hpr : ∀ S, HeadsKept (pr S)) (D : Doc MC)
(ht : ∀ m ∈ D.math, ck (topSym D) (pr (topSym D) m) = some [m])
(h : ∀ c ∈ D.comps, ∀ m ∈ c.math, ck (symFor D c) (pr (symFor D c) m) = some [m]) :
cookDoc ck (rawDoc pr D) = some D
Math entries read back when each one does under its table. The table is the same
on both sides: symFor
and topSym
read headers, never math, and the printer keeps
headers.
A container’s math printer and reader, entry by entry
def prMx (prE : Sym → Eqn → String) (prR : Sym → Json → String) (S : Sym) : MC → MR
Print a math entry with the container’s equation printer and expression printer.