Instructor guide

How the site is organised, what students see, how to author worksheets, and how to host material for a class.

Pages on this site

PageContents
compose.tstephen.comThe app — the single entry point since v1.2.0. It loads with one demo worksheet; everything else arrives through unlock codes (below), /?code=… links/QRs, or .compose.json files. Works without an account.
The built-in libraryLoaded on demand inside the app. Coppock & Champollion, Invitation to Formal Semantics (30 worksheets, §6–§13): whole collection code KT6WF4. Heim & Kratzer, Semantics in Generative Grammar (8 worksheets): code CETGZ4. Classic papers (Partee 1986, Partee & Rooth 1983, Montague’s PTQ, Davidson 1967, Krifka 1998, Barwise & Cooper 1981, Link 1983): code QIPYVM. Every chapter and single worksheet has a code of its own — find them in the app (⌗ buttons) or in the table below. Old links (/cc, /hk, /papers, chapter pages) redirect into the app and open the same content.
Sign-in pageNot a separate URL: the sidebar’s Account section on any of the pages above opens it. Students register free practice accounts (email + password, at least 10 characters); an instructor invite code entered on the same form creates an instructor account. No verification email is sent — the server sends no email at all.
Worksheet editorIn the app: sidebar → AuthorWorksheet editor (or ⌘E). Usable without an account; exports .compose.json; publishing to the server needs an instructor sign-in. The old /editor URL redirects here.
/dashThe original instructor dashboard, same accounts and versions as the in-app pages. Version management now lives in the app itself (sidebar → Assign & share → My versions); /dash remains for editing version notes and as a fallback.
/filesAll 46 built-in worksheets and both textbook bundles as downloadable .compose.json, with a site map.
/helpStudent reference (rules, symbols, grading) and worked derivation guides.
/aboutProject description, credits, citation formats, what accounts store.

Every documentation page in this table also opens inside the app: the sidebar’s Guide & help section (and the ⌘K palette’s Pages group) renders the guide, help, downloads and about pages in the app itself, with an “open standalone ↗” link back to the plain URL. The URLs above keep working for bookmarks, sharing and search engines.

The starter page: sidebar, exercises column, derivation tree, reference panel
compose.tstephen.com as it loads: the Getting Started demo worksheet, with the navigation sidebar expanded on the left, the exercises column beside it, the derivation tree centre, and the reference panel (on Lexicon) right.

What students see

The app is one window with four columns. The sidebar (left) holds navigation in accordion sections — Worksheets (the built-in library, My worksheets, and any unlocked classes; the curated library nests by book — a Coppock & Champollion and a Heim & Kratzer family drop down to their chapter collections, then to worksheet rows, with Classic papers a single collection alongside), Continue (recently opened exercises), Display (theme and layout options, plus actions such as saving progress to a file), Guide & help, and Account. It loads expanded by default and stays that way when you pick a worksheet or an exercise — the expanded sidebar and the exercises column coexist. Collapsing it to a 58px icon rail is a deliberate choice (the ⌘\ shortcut or the header button), and that choice persists. Picking a worksheet opens the exercises column: the worksheet’s derivations, grouped, with a done ring per solved item, and a tinted bar pinned to the foot of that column carrying the worksheet’s ⌗ code, ▦ QR & link, a progress summary, and the save-progress / reset-all-derivations actions. The stage (centre) shows the current derivation tree. The reference panel (right) has three tabs: Lexicon (the worksheet’s words with their typed denotations), Rules (the composition rules enabled in this worksheet, with a description and usage note each), and Notes (the worksheet’s reading companion, present when the worksheet has one). The panel opens on Lexicon by default and remembers whichever tab and open/closed state the student last chose; opening a worksheet never forces a particular tab.

The workflow per derivation: click a node whose children are resolved, choose a composition rule, type the β-reduced result, submit. The grader accepts any answer α-equivalent to the target after normalization; conjunct order does not matter. Choosing an inapplicable rule is refused with the reason (for example: “Both sisters must be predicates ⟨A,t⟩ of the same type A. The sisters are ⟨e,⟨e,t⟩⟩ and e.”).

Keyboard: the whole derivation loop is operable by keyboard, and node states are announced to screen readers. ⌘K (Ctrl+K) opens a command palette that searches worksheets, the current worksheet’s exercises, pages and actions; J/K step to the previous/next exercise; a shortcuts dialog listing the rest is in the palette’s Actions group.

A worksheet page: sidebar, exercises column, derivation tree, reference panel on Lexicon
The §7 adjectives worksheet, first derivation, with the reference panel on the Lexicon tab. Nodes marked “ready — select” have resolved children; leaves resolve from the lexicon.
The Rules tab of the reference panel listing FA, PM and NN
The Rules tab for a §7.2 worksheet: FA, PM and NN are enabled; PA, IFA, type-shifting and QR are not. The panel remembers the tab and open/closed state the student chose.
The rule chooser dock under the tree
The rule chooser, opened by selecting the DP node. Inapplicable rules remain listed; choosing one shows the type-theoretic reason it fails.

Input accepts ASCII shortcuts: Lx. → λx., & → ∧, ~ → ¬, -> → →, and a clickable symbol palette covers the rest. The palette shows only the operator symbols the current worksheet uses (a §6 worksheet shows no mereology or presupposition keys; the §10 worksheets show ∗ ⊕ ≤; the definedness and tense/modal worksheets show ∂ ⊤ ⊥).

Where the author provided them, derivations carry staged hints (revealed one at a time; the final stage offers “Show answer” unless the version is set up as an assessment). Exercises can anchor to sections of the notes; opening an exercise scrolls the Notes tab to its section.

A staged hint above the derivation
Hint 1 of 2 on the §7.2 worksheet’s first derivation. The built-in ch6 and ch7.1 worksheets ship two hints per derivation.
The Notes tab open next to a derivation
The Notes tab on the §7 worksheet showing section 7.2: prose, numbered examples, and a denotation table, with a contents bar at the top.

The layout adapts to screen width in three bands (v1.3.0). On tablets (760–1180px) the derivation stage is full-width under a slim app-bar; a ☰ button opens a left navigation drawer (the sidebar sections plus the drill-in exercises list), and a Reference button opens a right drawer with the Lexicon/Rules/Notes tabs. Both drawers slide over the stage with a dimmed backdrop and never shrink the tree. On phones (below 760px) the same content lives in a bottom tab bar — Derive, Exercises, Reference (the Lexicon/Rules/Notes tabs), and a Menu that carries the sidebar’s sections, unlock codes and settings. Worksheet-switching is on the Derive header and the Exercises tab; the phone’s switch sheet groups the library by book with a search box, and the Exercises tab ends in the same code / QR & link foot as the desktop exercises column.

The tablet layout: left navigation drawer over the full-width derivation stage
The tablet layout (760–1180px): the ☰ navigation drawer — worksheet sections, exercises and the code / QR & progress foot — slides over the full-width stage; the app-bar keeps the exercise steppers and the 𝑓 Reference drawer button.
The phone layout: derivation tree above the bottom tab bar
The phone layout: the full-width stage above the Derive · Exercises · Reference · Menu tab bar.

Progress. Progress is stored in the browser’s localStorage. Since v1.2.0 the app keeps ONE store for everything opened in it — the demo, the whole built-in library, loaded files — while each hosted version’s /v/ page keeps its own isolated store. (Progress students made on the retired /cc-style pages is migrated into the app store automatically on their first visit.) The sidebar’s Your progress page shows per-worksheet solved counts and has “Save to a file” / “Restore” buttons for moving progress between machines. A signed-in student’s progress additionally syncs to their account, so it follows them across browsers. The app registers a service worker on first visit and afterwards loads — including already-fetched library worksheets — without a network connection.

Getting material to students

Three ways, in the order we recommend them:

MethodBehaviour
An unlock codeFor hosted material you control (a version, below). Students sign in and enter the six-character code once; the class appears in their sidebar under My classes and their progress syncs to their account. You can change the content after distribution. Hosting a version is instructor-only — students can register, redeem codes and sync progress, but cannot publish hosted material.
A library code / QR / linkEvery built-in worksheet, chapter and whole collection has a fixed six-character code — no account needed on either side. Students enter it under “⊕ Unlock with a code” (or scan the QR / open the link, which encodes /?code=CODE): the content is fetched into the app, opens immediately, and stays in their sidebar under Unlocked. Students don’t see the full library by default, so the code is how you point a class at exactly the right shelf. Find the codes in the app: a worksheet’s ⌗ Code and ▦ QR & link buttons at the foot of its exercise list, the beside chapter headings and the Full-library rows (instructor sidebar) — or simply right-click any worksheet or chapter row in the sidebar: a small menu offers ⌗ Share code, ▦ QR & link and (on worksheets) ✎ Copy to editor. Your own hosted versions’ sidebar rows offer the same right-click share menu — there it carries the version’s unlock code, with ✎ Edit opening the hosted editor instead of Copy to editor. The whole-collection codes: C&C KT6WF4, H&K CETGZ4, papers QIPYVM. Chapter codes: cc/ch6 DXKHFU · cc/ch7 QI753D · cc/ch8 U9INJS · cc/ch10 JV5NKN · cc/ch11 F7Q8Y7 · cc/ch12 7N7UWF · cc/ch13 VYDXIG · hk/ch1 2U95R2 · hk/ch2 IWAHYZ · hk/ch4 YPEQCQ · hk/ch5 8IIRCE · hk/ch6 3FCWXC · hk/ch7 AUY39C · hk/ch9 C64QMV · hk/ch12 R53MVA · papers/partee 4UV9HE · papers/ptq JKTYCU · papers/krifka QGAWIZ · papers/davidson TRGU6C · papers/partee-rooth 3IKHNW · papers/barwise-cooper Y97C9T · papers/link SBG4MN.
/v/<slug>A version’s direct student link: the same content the unlock code enrols students in, without an account. Progress stays in that browser only. Kept for handout/QR distribution and as the no-account path; a printed link keeps working alongside the code.

Authoring worksheets

The editor runs without an account: open the sidebar’s Author section and pick Worksheet editor (or press ⌘E). A worksheet consists of: a domain (constants and variables with types), a lexicon (words with λ-denotations), a rule configuration, and exercises (groups of derivations, each a bracketed tree with optional targets, hints and notes anchors). The file format is JSON, documented in FORMAT.md; any worksheet from /files can be used as a template.

Authoring in the editor page, recorded end to end: title, two lexicon entries typed with live type-checking, an exercise with a derivation tree, and ▶ Load into app to try it as a student.

Opening and importing

The editor opens on the worksheet currently loaded in the app; pick a different one from the sidebar’s Worksheets section first, or use + New in the editor header for a blank sheet. To import, use the Author section’s Import worksheet… row or drop a .compose.json / .compose-bundle.json file anywhere onto the window. Imported and newly authored worksheets are stored in the browser and listed under My worksheets in the sidebar.

The worksheet editor page with its header strip and three columns
The editor page: back button and live save-status dot in the header strip; rules and domain left, lexicon centre, exercises right.

The editor surface

Left column: checkboxes for the five composition rules (FA, PM, NN, PA, IFA), the type-shifting inventory grouped by family (NP shifts, adjectives, closure, argument raising), behaviour switches (Quantifier Raising, auto-resolve non-branching nodes), and domain operators (∗ ⊕ ≤ ∂ ⊤ ⊥) — students’ symbol palettes show exactly the operators enabled here. Centre: the lexicon. Words are comma-separated for synonyms (runs,run); denotations are typed in ASCII (Lx.Ly.greet(y,x)). The engine parses each entry as you type and displays its computed type, or a parse error. Below the lexicon: constant declarations (f g : e) and variable-type declarations, with one-click additions for events, worlds, times, generalized quantifiers.

The editor: rules, live-typed lexicon, constants, variable types, exercise panel
The editor with three lexical entries typed in. The right-hand column of the lexicon shows the type the engine computed for each denotation: e, ⟨e,t⟩, ⟨e,⟨e,t⟩⟩.

Derivations

Right column: exercises. A derivation is a labelled-bracket tree — [.S [.DP Frodo ] [.VP runs ] ] — where leaves are lexicon words. Optional fields per derivation: a display sentence, an expected root denotation, a teacher-only note, and hints (one per line, revealed in order). ▶ Test solves the tree with the engine and shows the computed root meaning and type; the expected field shows ✓ if they match, ✕ if not. ▶ Load into app loads the worksheet as a student would see it.

An exercise with a tested tree and validated expected denotation
A tested derivation: the engine computed run(f) : t for the tree, matching the expected denotation (✓).

Notes

The Author section’s Notes row opens a two-pane editor: source on the left, rendered student preview on the right. The input format is Markdown for document structure with LaTeX for linguistic content — the full construct list is in the reference below. ## headings become sections; a derivation’s “section” field anchors it to one, and the student Notes tab scrolls there when the derivation is opened.

The notes editor: LaTeX source with live student preview
The notes editor. The source (left) uses \llbracket…\rrbracket, $…$, an expex example and a derivation environment; the preview (right) is what students see.

Saving and exporting

Header buttons: Save to library (stores in this browser), ▶ Load into app, and .json (downloads the worksheet source); signed-in instructors also get ⇗ Share · code + QR / ⇗ Host & get code here — hosting the current worksheet and opening the share dialog in one step (below). The .compose.json file is the worksheet: it is what you re-import, hand to students directly, or upload to a hosted version. To distribute worksheets to a class, host them in a version and share the unlock code or the /v/ link (below), or share the .compose.json file itself.

Notes input reference

Notes (worksheet reading companions and version notes) are written in Markdown with a fixed set of LaTeX constructs. The renderer implements the constructs below natively; commands outside this list are shown as literal source rather than dropped.

Document structure (Markdown)

InputResult
# A · ## B · ### CHeadings. ## headings are the anchors exercises can point to. \section{…}, \subsection{…}, \subsubsection{…} are equivalent.
blank lineParagraph break.
**bold**, *italic*, `code`bold, italic, code. \textbf, \emph/\textit, \texttt are equivalent; \textsc{…} renders small caps.
- item or \item inside itemize/enumerateList item.
[^a] + [^a]: text, or \footnote{text}Footnote; all footnotes are collected at the end with back-links.
\href{#g1.d2}{see (12)}A link that opens derivation d2 of group g1 in the current worksheet.

Math and denotations

InputRenders as
$\lambda x. \neg run(x)$ or \(…\)λx.¬run(x)
$$ … $$ or \[ … \]The same, as a centred display line.
<e,<e,t>> (in math)⟨e,⟨e,t⟩⟩
\llbracket runs \rrbracket, \den{runs}, \sv{runs}⟦runs⟧ (stmaryrd-style denotation brackets; ⟦…⟧ may also be typed directly, and [[…]] works inside math and derivation blocks)
x_1, x^2, x_{12}Sub/superscripts: x₁, x².
/\ \/ ~ -> <-> => |-> != <=∧ ∨ ¬ → ↔ ⇒ ↦ ≠ ≤
lambda forall exists iota (bare words in math)λ ∀ ∃ ι

Symbol commands available in math: Greek letters (\alpha\omega, \Gamma \Delta \Sigma \Pi \Omega); logic \neg \land \wedge \lor \vee \to \rightarrow \leftrightarrow \Rightarrow \Leftrightarrow \models \vdash \equiv; sets \in \notin \subseteq \subset \cup \cap \emptyset \varnothing \setminus; orders and mereology \leq \geq \sqsubseteq \sqcap \sqcup \oplus \otimes \ast \star; other \top \bot \partial \circ \cdot \times \mapsto \mid \neq \approx \sim \langle \rangle \ldots \cdots \prime. \text{…} and \mathrm{…} unwrap to plain text; \, and other spacing commands become spaces.

Numbered examples (expex, linguex, gb4e)

InputResult
\ex Frodo runs.
\xe
(1)  Frodo runs. — numbering is automatic and continuous through the document.
\pex Context sentence.
\a First variant.
\a *Second variant.
\xe
(2) with lettered sub-examples a., b. A leading * ? ?? ?* *? # % is set off as a judgment (glued or spaced).
\ex. Frodo runs.
\a. *Runs Frodo.
linguex equivalents of the above.
\begin{exe} \ex … \begin{xlist} \ex … \end{xlist} \end{exe}gb4e equivalents.
\ex<neg> … or \label{neg}, then \ref{neg} / \getfullref{neg}Label an example; references render as the example’s number — 3 / (3) — and click-scroll to it.

Glosses (expex \begingl)

Input:

\begingl
\gla neko-ga neru //
\glb cat-NOM sleep //
\glft 'the cat sleeps' //
\endgl

Result: word-aligned two-line gloss with the translation beneath. Leipzig abbreviations in the gloss line (NOM, 3SG, NEG, …) are set in small caps and show their expansion on hover. A \begingl block inside \ex…\xe attaches the gloss to that example's number.

Trees (qtree, forest)

Input, either form:

\Tree [.S [.NP Frodo ] [.VP runs ] ]

\begin{forest}
[S{run(f)} [DP{f} Frodo] [VP{Lx.run(x)} runs]]
\end{forest}

Result: a typeset syntax tree. {…} after a node label is a denotation, displayed under the category label. Wrapping a terminal in <…> draws a roof. Forest option preambles before the first bracket are ignored.

Denotation tables (COMPOSE-specific)

LaTeX has no standard environment for type-annotated denotation steps, so this one construct is COMPOSE's own. One step per line, expression : type; the types right-align into a column; indentation indents the row; blank lines leave a gap.

\begin{derivation}
[[runs]]       = Lx.run(x) : <e,t>
[[Frodo runs]] = run(f)    : t
\end{derivation}

There is also an avm environment for feature structures (ATTR: value per line, nesting with brackets, & and \\ row syntax accepted).

IPA (tipa subset)

\textipa{…} maps a subset of tipa ASCII to IPA: @→ə E→ɛ I→ɪ O→ɔ U→ʊ V→ʌ &→æ S→ʃ Z→ʒ T→θ D→ð N→ŋ ?→ʔ :→ː "→ˈ %→ˌ, among others. Unmapped characters pass through unchanged.

Hosting for a class

The hosted flow, end to end: create a version (a worksheet collection the server hosts for you) → choose what it contains on the Assign & share page → hand the version’s unlock code to your students → each student signs in and enters the code once. The class then appears in their sidebar under My classes, and their progress is kept on their account. Hosting versions is instructor-only and enforced by the server: a free student account can register, redeem codes and sync its progress, but cannot create or publish a hosted /v/ version. Your hosted versions also appear in your own sidebar under Worksheets → My versions: open a worksheet there to preview it exactly as an enrolled student sees it (progress shares the version’s store), or right-click a row for its code, QR and ✎ Edit.

Signed in as an instructor, sharing is also one click from the worksheet itself: the editor header shows ⇗ Share · code + QR for a hosted worksheet — or ⇗ Host & get code for one not hosted yet, which creates the version for you — and the same ⇗ Share button sits above a hosted worksheet’s derivation. Every entry point opens the share dialog, which leads with the unlock code (⧉ Copy, ↻ New code) and carries the QR code, the /v/ link and a printable handout below.

The instructor side, recorded end to end: signing in, the My versions page, copying the unlock code, the ⇗ Share dialog that leads with the code, and choosing the class content on the Assign & share page.

Accounts

Instructor registration needs an email address, a password of at least 10 characters, and an invite code (available from the administrator — see /about): open the sidebar’s Account section → Sign in → Register tab → “I have an invite code”. Students register on the same form without a code. No confirmation email is sent and there is no self-service password reset; a forgotten password is reset by the administrator. What an account stores is listed on /about.

The sign-in page with Log in and Register tabs
The sign-in page, reached from the sidebar’s Account section. The Register tab has the optional invite-code field; without a code it creates a student practice account.

Versions

A version is a hosted worksheet collection with its own unlock code and student URL. On the My versions page (sidebar → Assign & share): + New version creates one from a title; ⬆ New from bundle creates one from a .compose-bundle.json file. Each version row shows the published state (● live / ○ hidden — unpublished versions can’t be redeemed and their student link returns 404), the /v/… slug, worksheet and derivation counts, an opens counter, and, expanded: the worksheet list (one ✎ Edit per worksheet), the unlock code with ⧉ Copy and ↻ New code (regenerating invalidates the old code; existing enrolments keep working), bundle download/replace, and delete.

The My versions page with a version row expanded, showing the unlock code
The My versions page with one version expanded: worksheet list with per-worksheet ✎ Edit, unlock code with Copy and New code, bundle download/replace. (Screenshot from a local test instance of the same build.)

Content gets into a version three ways: pick worksheets on the Assign & share page (below), author in the editor and save to the version (✎ Edit on the version row or on any single worksheet inside it — both open the in-app editor), or import a bundle file. Every save is validated server-side: the same engine parses every worksheet and rejects the save with exact error paths (for example worksheets[0].content.lexicon[2].denotation) if anything fails; limits are 2 MB, 40 worksheets, 400 derivations per version, unique worksheet keys.

Assigning and sharing

The Assign & share page (sidebar section of the same name, or ☑ Assign on a version row) is where you choose what the class sees: the left column lists every worksheet you can reach (the built-in library, your own, the version’s current content), the right column shows the resulting student-visible set, the unlock code large with ⧉ Copy and ↻ New code, the /v/ link, and the published toggle. Saving replaces the version’s content — students see the change on their next load, without re-entering the code.

The Assign & share page: worksheet picker left, student-visible set and unlock code right
The Assign & share page. “What students get” ends with the unlock code to hand out.

To distribute: give students the code (say it, write it on the board, put it in the LMS). They sign in — creating the free account if needed — and enter it in the sidebar’s “⊕ Unlock with a code” row (on the phone, the ⊕ Unlock chip). Codes are case-insensitive; entering one twice is harmless.

The ⇗ Share dialog (on the My versions row, in the editor header, or above a hosted worksheet’s derivation) is the one complete share surface: the unlock code first, then the direct /v/<slug> link as text, a QR code, a PNG download and a printable A4 handout. The link and QR work without any account — use them where accounts are not wanted; progress then stays in each student’s browser instead of on an account, and enrolment counts are not tracked.

What the student link opens

/v/<slug> serves the same app, loaded with the version’s worksheets — the identical content an enrolled student sees under My classes, and the two share one progress record per browser. If the version has notes, students get the Notes tab; the Rules tab and hints work as on library pages.

The student page a version link opens
The student view of the version created above. This is what the /v/ link opens, and what an enrolled student sees in-app.

Files & offline use

The files page listing downloadable worksheets
/files: every worksheet and bundle as .compose.json, with titles and derivation counts.

Offline behaviour: the app works offline after a first visit, including library worksheets it has already fetched (service worker; /dash is never cached). Worksheets themselves travel as .compose.json files, which load on any COMPOSE page straight from disk.

Invite codes and questions: /about · source repository