Write statements
A write statement is a verb followed by its items. An item is a parenthesized block whose first token names its type; items may stand in any order. The construction that supplies the axis is an item like the others, so every slot of a write's signature is one block in the source, delimited on both sides and classified by its head.
flip takes no item. Round parentheses are items and braces are blocks
(def, on, export); no item uses braces. The side items name the side
of the axis that stays, toward, and the side that folds over, moving,
and select among the candidates of a construction by them
(Selection). The toward item of flatten selects among
states rather than among lines
(open-flatten-selection). The on item of
flatten names its anchor, the flap anywhere in the stack under the vertex
whose tip the fan moves; without it the anchor is the topmost flap there
(def-flatten). The other layers under the vertex stay
where they lie and need no rays. on names a flap by incidence for both
writes: the flap a mark scores, and the flap a flatten folds.
A head that does not belong to the verb is an error naming the verb and
the item (fold takes no (between) item), and an item type given
twice is an error at the second occurrence (only one moving item per fold). Each section below states one verb, with complete programs that
this page evaluates; a prelude block is a sheet that several of them start
from.
fold (map .a onto .c) (moving .a) (moving .c)error: only one moving item per fold --> BELOCH-WRITES.md:1:36 | 1 | fold (map .a onto .c) (moving .a) (moving .c) | ^^^^^^^^^ only one moving item per fold
mark
mark scores its line and moves nothing. The crease reads F in the
output, and a (mountain) or (valley) item records the intent the crease
pattern draws, which is no part of the state
(def-mark, Output format). Without on, a
mark scores every layer under its line or its extent, one piece per
layer; (on …) confines it to one flap (ADR 0036, ADR 0039).
Extent. The extent of a mark is its whole line, the stretch
(between .p .q) or the point (at .p); each point lies on the mark's
line (.p is not on the mark's line), and between takes two points
apart (the mark's extent needs two distinct points). An extent that
runs from boundary to boundary of its flap subdivides the flap; one that
ends inside a face subdivides nothing and dangles there as a record, which
later reads select and later folds carry like any material
(ADR 0033). A record is written to beloch:marks in the output,
and the crease pattern draws it apart from the creases
(Output format). The extent lies on the paper
(the mark's extent is not on the paper), and with on it stays on
the named flap: an extent that would cross a folded crease to reach its
endpoint is an error (the mark's extent from .p to .q crosses a folded crease (it leaves its flap)). A point of the extent that lies on a
crease several flaps share needs on with a second point to settle the
flap (.m lies on a crease shared by 2 flaps, hint name the flap with #[...]).
A line bound by = has no material until a mark scores it, and the meet
reads material only (Points): a line that
serves to locate a point is marked, with (at …) where it is to subdivide
nothing, and a line that only feeds a construction stays a value.
mark (through .b .d)
mark (map --ab onto --cd) (between .m .o) (mountain)1 assertion passed
assert faces = 1.r = free on --bc from .b at 1/2
.m = free on --bd from .b at 1/2 ; on the hinge, under both layers
mark (perp --bc through .r) (at .r) (on .m)error: .m lies on a crease shared by 2 flaps --> BELOCH-WRITES.md:3:1 | 1 | .r = free on --bc from .b at 1/2 2 | .m = free on --bd from .b at 1/2 ; on the hinge, under both layers 3 | mark (perp --bc through .r) (at .r) (on .m) | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ .m lies on a crease shared by 2 flaps = help: name the flap with #[...]
.r = free on --bc from .b at 1/2
.m = free on --bd from .b at 1/2
mark (perp --bc through .r) (at .r) (on #[.m .c]) ; the layer that holds .c1 assertion passed
assert faces = 2A fold has four parts (def-fold):
| part | item | what it is |
|---|---|---|
| axis | a construction, or a crease | the line the paper turns about |
| side | moving, toward, or derived | the side of the axis that folds over |
| depth | up to | the deepest flap that moves; without it, every layer on the side |
| placement | mountain, over, under | where the moved block lands: on top, underneath, or beside a flap |
Side. moving takes a flap operand and names the side of the axis
its image lies on, nothing more (Flaps).
(map .p onto .q) and (map .p onto --l …) derive the side from the
point they move, and (map --l onto --m) from the material of --l that
swings (Axiom 5, a line onto a line); a
written moving overrides the derived side. A fold along
(through …), along (perp …) or along an existing crease derives none
and needs moving or toward (this fold needs `moving .p` to choose the side). A point on the axis names no side (moving .p names no side of the fold line of <construction>), and a flap that straddles the
axis names none without a point.
fold (--d) (moving .b) (up to .c) ; along an existing crease
fold (map .a onto .d) (moving .a)
fold (through .m .n) (moving .b) (up to .b) (under .p)
fold (map .a onto .b) (moving .a) (mountain)2 assertions passed
assert steps = 4assert faces = 8fold (map .c onto .b) (up to .d) ; the depth needs no moving2 assertions passed
assert steps = 1assert faces = 2Depth. moving names the side that folds over and nothing more: a
fold takes every layer under its line on that side, and so does a
placed fold. (up to …) narrows it to the flap it names, the layers
outward of that flap, and every layer joined to those by a crease away
from the fold line, which the paper could not leave behind without tearing
(def-fold). For a fold placed over or under a flap,
the layers outward of the up to flap end at that flap: the fold takes
every layer between the two, hinged to the up to flap or not, and the
target and the layers beyond it stay. The depth is a flap, so its point
settles one flap: a point on a crease that several flaps share is an
error (.s lies on a crease shared by 2 flaps, hint name the flap with #[...]), and a crease as the depth needs moving to walk inward
from (`up to` a crease needs `moving` to walk inward from, hint
name the flap with a point instead).
.s = --d * --ab ; on the hinge, under both layers
fold (map .a onto .s) (moving .a) (up to .s)error: .s lies on a crease shared by 2 flaps --> BELOCH-WRITES.md:2:1 | 1 | .s = --d * --ab ; on the hinge, under both layers 2 | fold (map .a onto .s) (moving .a) (up to .s) | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ .s lies on a crease shared by 2 flaps = help: name the flap with #[...]
Placement. The moved block lands on top of the paper it folded from,
or underneath with (mountain). (over <flap>) and (under <flap>)
slide it into the stack beside a flap that stays
(ADR 0052): the target lies where the block lands, and the block
goes right above or right below it. The direction of a placed fold follows
from the placement, so (mountain) beside it is an error (a placed fold derives its direction, hint drop mountain). The target
stays (the placement target moves with the fold, hint name a stationary flap) and covers the landing (.p's flap does not cover where the moved material lands), and a block that would have to pass
through a layer on its way is refused (placing the moved material under .p would pierce another layer). The letter of the crease a fold
scores follows from the state it leaves
(def-letter): a fold through a stack reads
valley on a face-up layer and mountain on a face-down one, and flip
changes no letter.
fold (map .a onto .d) (moving .a)
fold (through .m .n) (moving .b) (under .p) ; without (up to .b) the whole layer would goerror: placing the moved material under .p would pierce another layer --> BELOCH-WRITES.md:2:1 | 1 | fold (map .a onto .d) (moving .a) 2 | fold (through .m .n) (moving .b) (under .p) ; without (up to .b) the whole layer would go | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ placing the moved material under .p would pierce another layer
Along an existing crease. fold (--d) folds along a crease the
program has scored, without restating its construction. The crease has to
lie on one line under the layers the fold reaches (the crease is bent under the moving flaps, hint select a straight segment with `&` or move fewer flaps, Filters), and it is
one crease: a union is refused (fold folds along one existing crease; a union spans several). With up to and into, a crease marked through
every layer folds some of them and keeps its name (The output clause,
below).
mark (through .a .c) as --ac
mark (through .b .d) as --bd
fold ([--ac --bd]) (moving .a)error: fold folds along one existing crease; a union spans several --> BELOCH-WRITES.md:3:1 | 1 | mark (through .a .c) as --ac 2 | mark (through .b .d) as --bd 3 | fold ([--ac --bd]) (moving .a) | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ fold folds along one existing crease; a union spans several
unfold
Section titled “”unfold turns layers back over a crease that every one of them lies
beside, and opens the folded hinges on it between the layers that turn and
the layers that stay (def-unfold). Its axis is a crease
the program has scored, and it scores none, so it takes no as or into.
(moving …) names the flap the turning layers grow from, and a word after
the flap says which layers turn with it: (moving .b up) the layers above
it, (moving .b down) the layers below it; (moving .b) is up. fold
takes neither word, and unfold takes no (mountain). (up to …) names a deeper flap to grow from. (toward …)
names a layer that stays; alone, it turns every layer on its side of the
crease that the same closure, run inward from it, leaves behind.
unfold (--q) (moving .b) ; the layer of .b and the two above it3 assertions passed
assert .b = (1/2, 0)assert .a = (0, 0)assert steps = 3unfold (--q) (toward .a) ; every layer but the one of .a2 assertions passed
assert .b = (1/2, 0)assert .a = (0, 0)unfold (--q) (moving .b down) ; the layer of .b and the one below it2 assertions passed
assert .a = (1/2, 0)assert .b = (1/2, 0)A fold along a line with all of the paper on one side of it fails, and its
message names unfold. A fold along hinges with paper on both sides of
them folds: the hinges on the line between the moving and the staying layers
open where they were folded and fold where they were flat. An unfold whose
layers would fold a flat hinge fails, and its message names fold.
fold (--q) (moving .b)error: every layer lies on one side of this line, so it does not separate the paper into two flaps and a fold along it has nothing to fold over; to turn layers over it about the hinges on it, write unfold --> BELOCH-WRITES.md:1:1 | 1 | fold (--q) (moving .b) | ^^^^^^^^^^^^^^^^^^^^^^ every layer lies on one side of this line, so it does not separate the paper into two flaps and a fold along it has nothing to fold over; to turn layers over it about the hinges on it, write unfold = help: unfold (…) (moving .p) turns the layers of .p over the line
reverse
Section titled “”reverse runs an inside or an outside reverse fold: the tip a line cuts
off a folded edge turns through its spine, as two placed folds over one
line (def-reverse, ADR 0043). It reads its axis
from a construction the way fold does, the tip the axis cuts off implies
the side, and (outside) asks for the outside reverse fold.
reverse (map .b onto .c)
reverse (map .d onto .c)3 assertions passed
assert .b = .cassert .d = .cassert faces = 6reverse (map .a onto .d) (outside)2 assertions passed
assert .a = .dassert faces = 4A tip of several layers can open in more than one place
(def-reverse). The reverse then fails, and its error
offers one letter item per opening: a letter on a hinge of the spine, named
by its crease and a point on it the way a ray of flatten is. On a square
folded in half twice, (--e & .q valley) keeps the opening between the two
inner layers, and (--e & .q mountain) the one below the outermost layer.
reverse (map .a onto .d)error: the tip opens at 2 places --> BELOCH-WRITES.md:1:1 | 1 | reverse (map .a onto .d) | ^^^^^^^^^^^^^^^^^^^^^^^^ the tip opens at 2 places = help: add one letter, which keeps one opening: (--e & .q mountain) or (--e & .q valley)
reverse (map .a onto .d) (--e & .q valley)2 assertions passed
assert .a = .dassert faces = 8squash
Section titled “”squash opens a flap of two layers hinged at a folded edge, its spine,
and presses it flat so that the spine lands on a target
(def-squash, ADR 0038). It is a fan at
the vertex, the end of the spine inside the paper: the spine opens, each
layer of the flap folds along its piece of the axis, and the layer of the
flap that the target line crosses folds along the target's crease.
Items. squash takes one item, a bare alignment: a line on the spine
onto its target, a line or a point, written without map or align,
(--h onto --ac) or (--h & --da onto .p). The write completes the
alignment with the fold line through the vertex: the axis is the bisector
of the spine's line and the target's line through that point. A
construction in its place is refused (squash completes the alignment with the fold line through the vertex; it takes no construction), and
so is every other head: the spine names the flap the squash folds, and
no item selects among its states.
Resolution. The spine is found by incidence: among the folded hinges
on the named line, the one whose one end lies inside the paper and whose
target lies on the flap's side of the spine's line. The anchor is the
flap of the upper layer at that hinge, and its sector beyond the target
line, away from the spine, stays. The target line carries the crease the
flap's layer folds along: with a line as target, that line's own crease;
with a point, the crease through the vertex and the point, which has to
exist (no crease lies on the line from the vertex through <p>, hint
mark it first). Several flaps with a spine on the line that the
target admits make the squash ambiguous (squash is ambiguous: <n> flaps have a spine on <l> that lands on <target>), and the hint names
the items that keep one: the spine's line filtered by a line through its
far end. A spine with both ends inside the paper has two vertices, and
which one the squash takes is not decided (both ends of the spine on <l> lie inside the paper; which one is the vertex is not decided,
ADR 0038). The crease the write scores is the axis, one crease with a piece on each
layer of the flap; a filter by flap, --s & #[.p], picks the piece on the
layer of .p. The checks the fan
runs after that stand in the kernel's tables (Fan).
The preliminary base, its front flap on the side of --da squashed onto
the center line, by a line and by a point on it:
squash (--h & --da onto --ac) as --s2 assertions passed
assert faces = 10assert .f = (1, 3/4).m = free on --ac from .a at 1/4
squash (--h & --da onto .m)2 assertions passed
assert faces = 10assert .f = (1, 3/4)On the base the spines of the front flap and of the back flap on that
side, --h & --da and --h & --bc, lie on one table edge, and both land
on --ac:
squash (--h onto --ac)error: squash is ambiguous: 2 flaps have a spine on --h that lands on --ac --> BELOCH-WRITES.md:1:1 | 1 | squash (--h onto --ac) | ^^^^^^^^^^^^^^^^^^^^^^ squash is ambiguous: 2 flaps have a spine on --h that lands on --ac = help: name the flap by its spine: (--h & --bc onto --ac) or (--h & --da onto --ac)
flatten and flip
Section titled “ and ”flatten folds the rays around one vertex in one move
(def-flatten). Some flat states are out of
reach of one simple fold at a time: the three angle bisectors of a
triangle with the altitude from their meeting point fold flat, the rabbit
ear 1, and no sequence of single folds reaches that
state 2. A statement folds one vertex; deciding
flat-foldability for a sheet of many vertices is NP-hard
3.
Items. A ray item names a piece of a marked crease at the vertex,
(--l) or (--l & .p), with mountain or valley after it where the
program fixes its letter; a bare ray is left to the solver. (.p over .q)
orders two sectors in the result, (staying <flap>) names the stayer,
the wedge that keeps its place, (on <flap>) names the anchor, and
(toward .p) selects among the states that remain. Every item but
toward is a constraint that narrows the set of states; toward picks
one of them. staying and toward stand at most once (only one staying item per flatten, only one toward item per flatten), and
an item that rules nothing out is no error.
The stayer. Without staying, the stayer is the wedge of less than a
half-turn between the folded rays of the first two ray items, so the
order of those two is part of the fold; the other items stand in any
order. Two leading rays on one line leave no such wedge
(collinear leading creases don't pick a stayer, hint add (staying .p)). With staying, the stayer is the one wedge whose
closure holds every named point, and the order of the rays says nothing
(<point> does not lie on the anchor, hint name a point on the flap the fan folds; no sector of the fan holds every staying point; the staying points lie in more than one sector, hint
add a point inside the sector that stays).
Resolution. A ray item resolves to every piece of its crease at the
vertex: a crease an earlier fold split at the vertex carries two, and
both are tried, with the states that keep the stayer still deciding
between them. & narrows a ray to one piece where both combinations
leave states (<name> is ambiguous at the vertex, hint select a segment with `&`). A ray with no material (--<name> has no material segment, no segment of <expr> matches) and an operand that is no
marked crease (collapse folds along existing creases; <operand> is not a material crease) are errors. The checks a flatten runs, with every
message, stand in the kernel's tables (Fan).
Selection. Where several states remain, toward .p selects in three
steps (open-flatten-selection): the
states whose moved material lies toward .p, among them those with the
fewest mountains on the rays the program gave, among those the one whose material
toward .p lies on top. A point on the line of a crease through the
vertex names no side (`toward` does not pick a side — the point is collinear with a crease through the vertex, hint aim it off the creases). Without toward, only the mountain count runs, and more than
one state left is an error (flatten is ambiguous: <n> realizations,
hint add (toward .p) to pick the fold direction); states that hold
different wedges still are one too (flatten is ambiguous: its candidates hold different sectors still, hint add (staying .p) with .p in the sector that stays). An over no state satisfies is
contradictory `over`.
The crease. With an even number of rays the crease a flatten scores is the bundle of the rays the program gave; with an odd number it is the emergent ray, the one crease no construction names, so a meet against the bound name finds where it reaches the edge. The letters in the output are those of the state (def-letter).
flatten (--ea) (--ec) (--eb) (toward .a) as --ear ; three rays: the fourth emerges
.t = --ear * --ab ; where the ear reaches the edge1 assertion passed
assert --ear is mountainflatten (--ea) (--ec) (--eb)error: flatten is ambiguous: 2 realizations --> BELOCH-WRITES.md:1:1 | 1 | flatten (--ea) (--ec) (--eb) | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ flatten is ambiguous: 2 realizations = help: add (toward .p) to pick the fold direction
flatten (--ea) (--ec) (--eb) (toward .b) ; .b lies on the line of --eberror: `toward` does not pick a side — the point is collinear with a crease through the vertex --> BELOCH-WRITES.md:1:1 | 1 | flatten (--ea) (--ec) (--eb) (toward .b) ; .b lies on the line of --eb | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `toward` does not pick a side — the point is collinear with a crease through the vertex = help: aim it off the creases
flatten (--eb & .b) (--ea & .a) (--ec & .c) (staying .d) (toward .a) as --ear1 assertion passed
assert --ear is mountainmark (through .a .c) as --d1
mark (through .b .d) as --d2
flatten (--d1 & .a) (--d1 & .c) (--d2 & .b mountain) (--d2 & .d)error: collinear leading creases don't pick a stayer --> BELOCH-WRITES.md:3:1 | 1 | mark (through .a .c) as --d1 2 | mark (through .b .d) as --d2 3 | flatten (--d1 & .a) (--d1 & .c) (--d2 & .b mountain) (--d2 & .d) | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ collinear leading creases don't pick a stayer = help: add (staying .p)
flip turns the whole sheet over and takes no item
(def-flip): every face changes between face up
and face down, and the stack reverses, so the layer at the bottom of a
pile is on top afterwards. Every hinge keeps its angle and its letter
(lem-flip); a fold that follows lands on what was
the back, and its crease reads mountain against the front where the same
fold before the flip would read valley. flip takes no axis: where the
sheet comes to lie on the table is settled up to a motion of the table,
and the kernel reflects it across a line of its own
(Flip).
flatten (--h & --bc) (--v & --cd) (--h & --da) (--v & --ab) (--bd & .b) (--bd & .d)
(.q over .r) (staying .a) (toward .q)
flip2 assertions passed
assert steps = 2assert faces = 6The output clause
Section titled “The output clause”The crease a write scores is its one output, and the clause after the items says what becomes of it, for every verb:
as --fbinds it to a new name:fold (map .a onto .c) (moving .a) as --f,flatten (--ba \ .a) … as --r. A name already bound is an error;as --f!rebinds it, with the!of The rule of rebinding.into --ladds it to the crease--l:mark (--l) into --ldraws the full line through a reference mark,fold (--d) (moving .b) (up to .c) into --dfolds some layers of a crease marked through all of them and keeps one name for the material. The new material must lie on the table line of a segment of--l; material on another line is a crease of its own, and[--l --m]is the read that unites two.- no clause: an anonymous crease, addressable by incidence only.
= binds the value of a read and nothing else, so the sort of a name is
visible at its binding: --l = (map .a onto .c) is a line with no
material, fold (map .a onto .c) as --l is a crease. A value bound by =
is a snapshot and takes no into; a new value is a new binding.
into takes a crease the program has scored: a name no statement bound
(--zz is not bound, hint write as --zz to name a new crease), a
line bound by = (into needs a crease; --l is a line), a selection
from other creases (into needs a crease of its own; --s is a selection from others) and a paper edge (into needs a scored crease; --ab is a paper edge) are errors, and so is new material off every segment of the
crease (the material this scores lies on no segment of --ac, hint
name it with as instead).
mark (through .a .c) as --ac
mark (through .b .d) into --acerror: the material this scores lies on no segment of --ac --> BELOCH-WRITES.md:2:22 | 1 | mark (through .a .c) as --ac 2 | mark (through .b .d) into --ac | ^^^^^^^^^ the material this scores lies on no segment of --ac = help: name it with as instead
mountain is a value of the placement type, so (mountain) beside (over …) puts two values in one slot; the placement item has already fixed the
direction, and the error says so: a placed fold derives its direction,
with the hint drop mountain.
fold (map .a onto .c) (moving .a) (over .b) (mountain)error: a placed fold derives its direction --> BELOCH-WRITES.md:1:46 | 1 | fold (map .a onto .c) (moving .a) (over .b) (mountain) | ^^^^^^^^ a placed fold derives its direction = help: drop mountain
Marking every argument as a block is what the model's operation signatures ask for: one item per parameter, the same shape for every write. For the tools it means that an item is one node of the syntax tree with a type of its own, so that highlighting colors an anchor, a placement and a construction differently, and a malformed item is contained by its parentheses instead of swallowing the rest of the statement.
Program
paper square
fold (map .b onto .a)
.p = free on --bc from .b at 1/4
.q = free on --ab from .b at 1/4
fold (through .p .q) (moving .b) as --fFigure 7.1 The first fold carries a single item, the construction (map .b onto .a), and reads its anchor from the corner that alignment moves. The second carries two: (through .p .q) is the line the paper turns about, (moving .b) the side that folds over, whose layers all travel. With no placement item the block lands on top of the paper it was folded from, and as --f gives the crease a name later statements can select.
Program
paper square
fold (map .a onto .c) as --bd
reverse (map .b onto .c) as --h
reverse (map .d onto .c) as --vFigure 7.2 Two reverse folds turn the triangle into the preliminary base. reverse reads its axis from a construction the way fold does, and the anchor is implied by the tip the axis cuts off, so neither write needs a (moving …) item.
Program
paper square
mark (through .a .c) as --ac
.m = free on --da from .a at 1/2
.o = free on --ac from .a at 1/2
mark (map --ab onto --cd) (on #[.c]) (between .m .o) (mountain) as --hFigure 7.3 mark scores paper without moving it. (between .m .o) cuts the score back to the stretch between two points, (on #[.c]) names the flap it runs on, and (mountain) records the intent the crease pattern draws.
Program
paper square
mark (through .a .c) as --ac
mark (through .b .d) as --bd
mark (map --ab onto --cd) as --h
mark (map --da onto --bc) as --v
.q = free on --ab from .a at 1/4
.r = free on --ab from .b at 1/4
flatten (--h & --bc) (--v & --cd) (--h & --da) (--v & --ab) (--bd & .b) (--bd & .d) (.q over .r) (toward .q)Figure 7.4 One flatten collapses six of the eight rays at the paper center into the preliminary base, and the diagonal through .a and .c stays flat. Each ray item picks a piece of a marked crease with &, (.q over .r) fixes which quarter comes to the front, and (toward .q) chooses one of the flat states the rays allow.
Program
paper square
flip
fold (map .a onto .c) as --gFigure 7.5 flip takes no item at all. It turns the sheet over, so the fold that follows is placed on what was the back, and --g comes out mountain where the same fold on an unflipped sheet would read valley.
Thomas C. Hull, Origametry: Mathematical Methods in Paper Folding (Cambridge University Press, 2020), https://doi.org/10.1017/9781108778633.↩
Erik D. Demaine and Joseph O’Rourke, Geometric Folding Algorithms: Linkages, Origami, Polyhedra (Cambridge University Press, 2007), sec. 14.1.1.↩
Thomas C. Hull, Origametry: Mathematical Methods in Paper Folding (Cambridge University Press, 2020), sec. 6, https://doi.org/10.1017/9781108778633.6.↩