Optional geometry and self-referencing constraints
The book, adam-web-ui, and adam-lsp explicitly install cel-std operations,
cel-euclid operations, and the seven geometry cell types. A standalone
adam-lang host still chooses its own libraries; Adam has no mandatory geometry
dependency. Enable cel-euclid’s adam Cargo feature, call
cel_euclid::register_adam_types(&mut types) and
cel_euclid::install(&mut lookup), and construct AdamParser::new(types, lookup).
Pass the same registry and lookup to adam_lang::check_sheet for editor checking.
The checker uses exact record/member metadata where types are known, visits
closure bodies, and defers unresolved call-result and tuple shapes to runtime.
It does not claim complete inference.
Geometry uses concrete f64 / UnknownUnit aliases, not generic Adam types.
Write 1.0 or 1 as f64 rather than passing i32 fields implicitly.
Field order is arbitrary; every declared field must occur once. Consult the
complete signature table
for fields, supported operand types, checked errors, and containment semantics.
Crop and straighten
This is the actual library example, included rather than copied. Run
cargo run -p cel-euclid --features adam --example adam_geometry to execute it.
cargo test -p adam-lang-book --test geometry verifies these same included
sheets through the book’s parser. These cross-library demonstrations are
executable Rust-driven examples, not live inspector mounts or a crop UI.
#![allow(unused)]
fn main() {
// Image coordinates -> crop coordinates. The caller rotates about the image
// point under the requested crop center. No separate requested-crop cell:
// Adam preserves the source aspiration of the self-referencing crop.
// A valid result preserves the crop center, image anchor, and all overlay
// corners within 64 epsilon times the requested maximum extent. Insufficient
// precision fails an explicit requirement, even with finite coefficients.
sheet crop_straighten {
source image: Rect = Rect {
origin: Point2D { x: 0.0, y: 0.0 },
size: Size2D { width: 100.0, height: 100.0 }
} require {
@valid_image image.is_finite() && image.width > 0.0 && image.height > 0.0
&& image.max_x > image.min_x
&& image.max_y > image.min_y
&& Point2D { x: image.max_x, y: image.max_y }.is_finite();
};
source transform: Transform2D = identity_transform();
cell crop: Rect = Rect {
origin: Point2D { x: 0.0, y: 0.0 },
size: Size2D { width: 100.0, height: 100.0 }
} require {
@positive_effective_crop crop.is_finite() && crop.width > 0.0 && crop.height > 0.0
&& crop.max_x > crop.min_x
&& crop.max_y > crop.min_y
&& Point2D { x: crop.max_x, y: crop.max_y }.is_finite();
};
cell shrink: f64 = 1.0 require {
@representable_shrink shrink > 0.0 && shrink <= 1.0
&& 1.0 / shrink <= 1.7976931348623157e308;
};
cell precise: bool = true require {
@sufficient_fit_and_presentation_precision precise;
};
// Map the effective crop back onto the unchanged source overlay.
cell presentation: Transform2D = identity_transform() require {
@finite_presentation presentation.is_finite();
};
relationship {
(crop, shrink, precise, presentation) := (|
r: Rect,
i: Rect,
inv: Transform2D,
t: Transform2D
|
(|r: Rect, i: Rect, inv: Transform2D, t: Transform2D, a: Point2D, b: Rect|
(|
r: Rect,
inv: Transform2D,
t: Transform2D,
s: f64,
accurate: bool
| // Eight epsilon inward guard, only when shrinking.
(|r: Rect, inv: Transform2D, t: Transform2D, s: f64, accurate: bool|
(|
r: Rect,
inv: Transform2D,
t: Transform2D,
s: f64,
accurate: bool,
q: Rect
|
(|
r: Rect,
inv: Transform2D,
s: f64,
accurate: bool,
q: Rect,
p: Transform2D
| // Finite coefficients alone do not guarantee a fixed
// anchor or overlay after reciprocal-scale cancellation.
(|
r: Rect,
s: f64,
accurate: bool,
q: Rect,
p: Transform2D,
a: Point2D,
lo: Point2D,
lr: Point2D,
ul: Point2D,
hi: Point2D,
e: f64
|
(
q,
s,
accurate
&& abs(q.width / r.width - s)
<= 0.000000000000014210854715202004 * s
&& abs(q.height / r.height - s)
<= 0.000000000000014210854715202004 * s
&& abs(q.center().x - r.center().x) <= e
&& abs(q.center().y - r.center().y) <= e
&& abs(a.x - r.center().x) <= e
&& abs(a.y - r.center().y) <= e
&& abs(lo.x - r.min_x) <= e
&& abs(lo.y - r.min_y) <= e
&& abs(lr.x - r.max_x) <= e
&& abs(lr.y - r.min_y) <= e
&& abs(ul.x - r.min_x) <= e
&& abs(ul.y - r.max_y) <= e
&& abs(hi.x - r.max_x) <= e
&& abs(hi.y - r.max_y) <= e,
p
))(
r,
s,
accurate,
q,
p,
p.transform_point(inv.transform_point(r.center())),
p.transform_point(inv.transform_point(q.origin)),
p.transform_point(
inv.transform_point(Point2D { x: q.max_x, y: q.min_y })
),
p.transform_point(
inv.transform_point(Point2D { x: q.min_x, y: q.max_y })
),
p.transform_point(
inv.transform_point(Point2D { x: q.max_x, y: q.max_y })
),
0.000000000000014210854715202004 * max(r.width, r.height)
))(
r,
inv,
s,
accurate,
q,
t.then(translation(Vector2D { x: -q.center().x, y: -q.center().y }))
.then(scale(1.0 / s, 1.0 / s))
.then(
translation(Vector2D { x: q.center().x, y: q.center().y })
)
))(
r,
inv,
t,
s,
accurate,
if s == 1.0 {
r
} else {
Rect {
origin: r.center()
- Vector2D { x: r.width * s * 0.5, y: r.height * s * 0.5 },
size: r.size * s
}
}
))(
r,
inv,
t,
if s == 1.0 { s } else { s * (1.0 - 0.0000000000000017763568394002505) },
accurate
))(
r,
inv,
t,
min(
1.0,
min(
min(a.x - i.min_x, i.max_x - a.x) / max(a.x - b.min_x, b.max_x - a.x),
min(a.y - i.min_y, i.max_y - a.y) / max(a.y - b.min_y, b.max_y - a.y)
)
), // Bound subtraction must retain the affine half-extents
// within 32 epsilon; reject cancellation, not an undersized
// but plausible result. This is a precision check only.
abs(
max(a.x - b.min_x, b.max_x - a.x)
/ (abs(inv.m11) * (r.width * 0.5) + abs(inv.m21) * (r.height * 0.5))
- 1.0
)
<= 0.000000000000007105427357601002
&& abs(
max(a.y - b.min_y, b.max_y - a.y)
/ (abs(inv.m12) * (r.width * 0.5) + abs(inv.m22) * (r.height * 0.5))
- 1.0
)
<= 0.000000000000007105427357601002
))(r, i, inv, t, inv.transform_point(r.center()), inv.outer_transformed_rect(r)))(
crop,
image,
transform.inverse(),
transform
);
}
out anchor: Point2D := transform.inverse().transform_point(crop.center()) require {
@feasible_anchor anchor.is_finite() && anchor.x > image.min_x && anchor.x < image.max_x
&& anchor.y > image.min_y
&& anchor.y < image.max_y;
};
// Closed-edge coverage, not Euclid's half-open point containment.
// Use the image coordinate/extent scale for the absolute rounding budget.
out coverage: bool := (|b: Rect, i: Rect, e: f64|
b.min_x >= i.min_x - e && b.max_x <= i.max_x + e && b.min_y >= i.min_y - e
&& b.max_y <= i.max_y + e)(
transform.inverse().outer_transformed_rect(crop),
image,
0.000000000000014210854715202004
* max(
max(image.width, image.height),
max(
max(abs(image.min_x), abs(image.max_x)),
max(abs(image.min_y), abs(image.max_y))
)
)
) require {
@closed_edges coverage;
};
}
}
Coordinate frames and source memory
image is an axis-aligned source-image rectangle. transform maps image points
to the frame containing the axis-aligned requested crop. The runner constructs
straightening rotations around the source-image point under the crop center.
The relationship also works with arbitrary invertible affine translations,
nonuniform scales, reflections, and shears; it does not assume a rotation or
an origin-centered anchor.
The relationship reads and writes crop. Adam preserves the user’s source
aspiration while it recomputes the effective value. Tightening the angle shrinks
the crop uniformly; loosening it springs back. An explicit crop write replaces
the aspiration. There is no extra requested-crop cell or helper-owned memory.
Every typed, noncapturing IIFE forwards its needed values explicitly.
The expression maps the requested center and the four-corner outer bounds through the inverse transform. It divides each nearest-image-edge distance by the corresponding maximum inverse half-extent, then selects the minimum with one. This gives the largest uniform shrink about that center. Bounding the transformed image instead would include uncovered regions under rotation or shear. A crop with an infeasible center is an error; translating it is not a valid repair.
Numerical and error contract
Inputs need finite positive image/crop sizes, advancing finite endpoints, a finite center, a checked invertible transform, representable inverse bounds, and an image anchor strictly inside all four image edges. The runner’s validation-only write boundary checks candidates before changing source cells. It uses the general checked inverse and bounds operations, not a Rust fitting calculation.
The CEL relationship leaves a fitting crop bit-for-bit unchanged. When it must
shrink, it multiplies the computed factor by 1 - 8*f64::EPSILON to round
conservatively inward. The precise flag rejects inverse-bound cancellation
that differs from affine support half-extents by more than 32*EPSILON; it also
rejects subnormal rounding that changes either uniform size ratio by more than
64*EPSILON relative to the shrink factor. The relationship computes the fitted
crop and its presentation together, while the source request is still available.
It checks the fitted center, the presented source-image anchor, and all four
effective corners mapped through the inverse and presentation against the
requested center and overlay corners. Each component must agree within
64*EPSILON * max(requested.width, requested.height). A large absolute overlay
offset does not relax this extent-relative budget. Finite presentation
coefficients alone do not guarantee these postconditions: reciprocal-scale
cancellation can move the anchor or distort the overlay.
The named sufficient_fit_and_presentation_precision requirement reports
insufficient precision, even when fitting, coverage, and coefficient finiteness
pass. The precise flag is validation metadata, not another requested rectangle.
The expression contains these policies openly, without a crop-specific operation.
Acceptance uses a 64*f64::EPSILON scale-relative tolerance for closed-edge
coverage, center preservation, maximality, and repeated application. For image
coverage the scale is the maximum image extent or absolute image endpoint;
crop-center and presentation comparisons use the requested overlay extent as
specified above. For dimensionless maximality comparisons the scale is one.
Ordinary Euclid point
containment is half-open; crop coverage allows corners on maximum edges.
The conservative result is maximal within this tolerance, not an exact-real
arithmetic guarantee. Identity preserves a fitting crop exactly; applying the
expression to its effective crop again is stable within tolerance.
Finite extreme magnitudes are supported when these computations remain representable. Nonfinite values, singular/lost-cofactor inverses, overflow, complete underflow, collapsed endpoints, infeasible centers, zero effective sizes, unrepresentable reciprocal scales, or insufficient precision produce a checked evaluation error or a named failed Adam requirement. Propagation alone does not mean requirements passed: the runner checks every requirement and refuses invalid effective values. Inspect errors and requirements instead of silently accepting an empty or numerically misleading crop.
Presentation
The runner reads parsed.sheet.source::<Rect>(crop_id) for the unchanged
overlay, never the previously fitted value. shrink describes the current
source-to-effective size ratio. presentation applies the image transform and
then its reciprocal shrink around the same crop center. Thus the effective
crop fills the original overlay and the same image anchor stays under its
center, provided the explicit precision requirement passes. In a.then(b),
a runs first. A fixed anchor alone does not certify the overlay corners.
The executable chapter test also covers unequal source/overlay magnitudes.
With scale(3.0, 3.0), an image centered at zero of size 1e-6 × 1e-6 and a
requested crop centered at zero of size 1e6 × 1e6 pass, preserving the center
and overlay mapping despite a shrink near 3e-12. In contrast, an image with
both origin coordinates 0.03333283332557231 and size 1e-6 × 1e-6, and a
requested crop with both origin coordinates -499999.9 and size 1e6 × 1e6,
fail the precision requirement under the same transform. All presentation
coefficients remain finite, but the anchor maps to 0.10000228881835938
instead of the requested 0.09999999997671694, exceeding the approximately
1.42e-8 overlay budget. Rejection preserves the source aspiration; it does not
translate the crop or silently narrow support to rotations or uniform scales.
For a [0,100] × [0,100] image, a centered square at 45 degrees has side
100 / sqrt(2) within 1e-12. For [0,100] × [0,80] with a requested
80 × 40 crop centered at (20,40), identity yields origin (0,30) and
size (40,20) within tolerance. The center never moves to hide infeasibility.
Pan and zoom policy
#![allow(unused)]
fn main() {
// Standalone demonstration; the live graph owns a separate Adam sheet.
// content includes the renderer's fit margin; empty content uses the viewport.
sheet pan_zoom {
source content: Rect = Rect {
origin: Point2D { x: 0.0, y: 0.0 },
size: Size2D { width: 100.0, height: 100.0 }
};
source viewport: Size2D = Size2D { width: 200.0, height: 200.0 } require {
@nonzero_viewport viewport.is_finite() && viewport.width > 0.0 && viewport.height > 0.0;
};
out bounds: Rect := if content.width > 0.0 && content.height > 0.0 { content } else {
Rect { origin: Point2D { x: 0.0, y: 0.0 }, size: viewport }
};
out fit_scale: f64 := min(
viewport.width / max(bounds.width, 1.0),
viewport.height / max(bounds.height, 1.0)
);
out fit_pan: Vector2D := Vector2D {
x: viewport.width * 0.5 - fit_scale * bounds.center().x,
y: viewport.height * 0.5 - fit_scale * bounds.center().y
};
cell zoom: f64 = 2.0;
cell pan: Vector2D = Vector2D { x: 0.0, y: 0.0 };
relationship { zoom := clamp(zoom, fit_scale, max(fit_scale, 8.0)); }
relationship {
// Compare actual endpoints: extent arithmetic can round differently at fit.
pan := Vector2D {
x: if viewport.width - zoom * bounds.max_x >= -zoom * bounds.min_x {
viewport.width * 0.5 - zoom * bounds.center().x
} else {
clamp(pan.x, viewport.width - zoom * bounds.max_x, -zoom * bounds.min_x)
},
y: if viewport.height - zoom * bounds.max_y >= -zoom * bounds.min_y {
viewport.height * 0.5 - zoom * bounds.center().y
} else {
clamp(pan.y, viewport.height - zoom * bounds.max_y, -zoom * bounds.min_y)
}
};
}
out view: Transform2D := scale(zoom, zoom).then(translation(pan));
}
}
The caller supplies measured visible-node bounds including the fit margin and
a positive viewport. Empty content falls back to viewport bounds. Fit uses
min(viewport.width / max(width,1), viewport.height / max(height,1)).
Zoom clamps to [fit_scale, max(fit_scale,8)]. Each pan axis centers undersized
content; otherwise it clamps to the actual scaled content edges.
Self-referencing writes retain pan/zoom aspirations. For initial fit or reset,
the caller writes fit_scale to zoom and fit_pan to pan.
This standalone sheet demonstrates the policy. The live graph uses its own
Adam sheet in adam-web-ui, with a Dioxus proposal/approval bridge shared by
Begin’s desktop and web builds and the book’s graph inspectors. JavaScript owns
measurement, layout, and gestures, but renders only matching Adam approvals.
The bridge waits for real positive viewport observations and retains the last
valid viewport during transient zero-size observations. See
graph view ownership and verification
for the live model, lifecycle, and interaction contracts.