sim-shape 0.1.3

Shape algebra, comparison, and match-hook helpers.
Documentation
# sim-shape Human Docs

<!-- GENERATED BY xtask simdoc; DO NOT EDIT. -->

This lane contains human-readable guides generated by `xtask simdoc`.

## Index Backlinks

This generated lane consumes `docs/generated/sim-index-fragment.sx`. Global index consumers merge that fragment into `docs/index/overview.md`, `docs/index/features.md`, and the package maps.

| Index row | Kind | Title |
| --- | --- | --- |
| `repo/sim-shape` | `repo` | sim-shape |
| `doc-set/sim-shape/generated` | `doc-set` | sim-shape generated docs |

## Feature Rows

| Feature | Subject | Specimens | Summary |
| --- | --- | ---: | --- |
| `feature/sim-shape/shape` | `crate/sim-shape` | 1 | Define reusable Shape matching, binding, citizen projection, and grammar contracts for runtime values. |
| `feature/sim-shape/shape-recipes` | `crate/sim-shape-recipe-exact-bool-shape` | 0 | Carry runnable Shape recipe crates used as checked examples for exact booleans and grammar contracts. |
| `feature/sim-shape/contract-emitter` | `crate/xtask` | 0 | Emit generated repository contract and index fragments for Shape crates. |

## Surfaces

| Surface | Kind | Subject |
| --- | --- | --- |
| `cli/sim-shape-recipe-exact-bool-shape` | `cli` | `crate/sim-shape-recipe-exact-bool-shape` |
| `cli/sim-shape-recipe-shape-grammar-contract` | `cli` | `crate/sim-shape-recipe-shape-grammar-contract` |
| `cli/xtask` | `cli` | `crate/xtask` |
| `docs/sim-shape/generated` | `docs` | `doc-set/sim-shape/generated` |

## Recipes

- `recipes/01-basics/chapter.toml`
- `recipes/01-basics/exact-bool-shape/Cargo.toml`
- `recipes/01-basics/exact-bool-shape/README.md`
- `recipes/01-basics/exact-bool-shape/expected.txt`
- `recipes/01-basics/exact-bool-shape/recipe.toml`
- `recipes/01-basics/exact-bool-shape/src/main.rs`
- `recipes/01-basics/shape-grammar-contract/Cargo.toml`
- `recipes/01-basics/shape-grammar-contract/README.md`
- `recipes/01-basics/shape-grammar-contract/expected.txt`
- `recipes/01-basics/shape-grammar-contract/recipe.toml`
- `recipes/01-basics/shape-grammar-contract/src/main.rs`
- `recipes/book.toml`

## Worked Examples

### `feature/sim-shape/shape`

Specimen `spec-test/sim-shape/src/citizen/inventory` is checked by `cargo test`.

Source `src/citizen/inventory.rs`:

```rust
//! Shape citizen inventory: registers every shape class and constructor with
//! the linker and provides the conformance fixtures that exercise them.

use std::sync::Arc;

use sim_kernel::{Cx, Error, Expr, Linker, ObjectEncoding, Result, Symbol, Value};

use crate::{
    AcceptOnNoDiagnosticsHook, AnyShape, DiscardOnDiagnosticPrefixHook, ExactExprShape, ExprKind,
    OrStrategy, ScoreFloorHook, ShapeDefRef, TableExtraPolicy, TableFieldSpec, TraceMarkHook,
    VennShapeSet, hook_value,
};

use super::construct::{
    and_shape_value, any_shape_value, class_shape_value, construct_accept_on_no_diagnostics_hook,
    construct_and_shape, construct_any_shape, construct_class_shape,
    construct_discard_on_diagnostic_prefix_hook, construct_exact_expr_shape,
    construct_expr_kind_shape, construct_hooked_shape, construct_list_shape, construct_not_shape,
    construct_or_shape, construct_repeat_shape, construct_score_floor_hook,
    construct_shape_def_ref, construct_shape_defs, construct_table_shape,
    construct_trace_mark_hook, construct_venn_shape_set, exact_expr_shape_value,
    expr_kind_shape_value, hooked_shape_value, list_shape_value, not_shape_value, or_shape_value,
    repeat_shape_value, shape_def_ref_value, shape_defs_value, table_shape_value,
};
use super::{
    and_shape_class_symbol, any_shape_class_symbol, class_shape_class_symbol,
    exact_expr_shape_class_symbol, expr_kind_shape_class_symbol, hooked_shape_class_symbol,
    list_shape_class_symbol, not_shape_class_symbol, or_shape_class_symbol,
    register_shape_citizen_class, repeat_shape_class_symbol, shape_def_ref_class_symbol,
    shape_defs_class_symbol, table_shape_class_symbol, venn_shape_set_class_symbol,
};

fn shape_fixture_wrong_version(cx: &mut Cx, value: Value) -> Result<()> {
    let Some(encoder) = value.object().as_object_encoder() else {
        return Err(Error::Eval("fixture has no object encoder".to_owned()));
    };
    let ObjectEncoding::Constructor { mut args, .. } = encoder.object_encoding(cx)? else {
        return Err(Error::Eval(
            "shape fixture expected constructor encoding".to_owned(),
        ));
    };
    args[0] = Expr::Symbol(Symbol::new("v999999"));
    sim_citizen::check_value_fixture_with_wrong_version(cx, value, Some(args))
}

fn conformance_any_shape(cx: &mut Cx) -> Result<()> {
    shape_fixture_wrong_version(cx, any_shape_value())
}

fn conformance_exact_expr_shape(cx: &mut Cx) -> Result<()> {
    shape_fixture_wrong_version(cx, exact_expr_shape_value(Expr::Bool(true)))
}

fn conformance_expr_kind_shape(cx: &mut Cx) -> Result<()> {
    shape_fixture_wrong_version(cx, expr_kind_shape_value(ExprKind::Number))
}

fn conformance_class_shape(cx: &mut Cx) -> Result<()> {
    shape_fixture_wrong_version(cx, class_shape_value(any_shape_class_symbol()))
}

fn conformance_list_shape(cx: &mut Cx) -> Result<()> {
    shape_fixture_wrong_version(cx, list_shape_value(vec![Arc::new(AnyShape)], None)?)
}

fn conformance_table_shape(cx: &mut Cx) -> Result<()> {
    shape_fixture_wrong_version(
        cx,
        table_shape_value(
            vec![TableFieldSpec {
                key: Symbol::new("ok"),
                required: true,
                shape: Arc::new(AnyShape),
            }],
            TableExtraPolicy::Reject,
        )?,
    )
}

fn conformance_or_shape(cx: &mut Cx) -> Result<()> {
    shape_fixture_wrong_version(
        cx,
        or_shape_value(
            vec![
                Arc::new(ExactExprShape::new(Expr::Bool(false))),
                Arc::new(ExactExprShape::new(Expr::Bool(true))),
            ],
            OrStrategy::FirstMatch,
        )?,
    )
}

fn conformance_and_shape(cx: &mut Cx) -> Result<()> {
    shape_fixture_wrong_version(
        cx,
        and_shape_value(vec![
            Arc::new(AnyShape),
            Arc::new(ExactExprShape::new(Expr::Bool(true))),
        ])?,
    )
}

fn conformance_not_shape(cx: &mut Cx) -> Result<()> {
    shape_fixture_wrong_version(
        cx,
        not_shape_value(Arc::new(ExactExprShape::new(Expr::Bool(false))))?,
    )
}

fn conformance_repeat_shape(cx: &mut Cx) -> Result<()> {
    shape_fixture_wrong_version(cx, repeat_shape_value(Arc::new(AnyShape), 1, Some(2))?)
}

fn conformance_shape_defs(cx: &mut Cx) -> Result<()> {
    let node = Symbol::new("Node");
    shape_fixture_wrong_version(
        cx,
        shape_defs_value(
            Arc::new(ShapeDefRef::new(node.clone())),
            vec![(node, Arc::new(AnyShape))],
        )?,
    )
}

fn conformance_shape_def_ref(cx: &mut Cx) -> Result<()> {
    shape_fixture_wrong_version(cx, shape_def_ref_value(Symbol::new("Node")))
}

fn conformance_hooked_shape(cx: &mut Cx) -> Result<()> {
    shape_fixture_wrong_version(
        cx,
        hooked_shape_value(Arc::new(AnyShape), vec![Arc::new(TraceMarkHook)])?,
    )
}

fn conformance_trace_mark_hook(cx: &mut Cx) -> Result<()> {
    shape_fixture_wrong_version(cx, hook_value(Arc::new(TraceMarkHook)))
}

fn conformance_score_floor_hook(cx: &mut Cx) -> Result<()> {
    shape_fixture_wrong_version(cx, hook_value(Arc::new(ScoreFloorHook::new(42))))
}

fn conformance_accept_on_no_diagnostics_hook(cx: &mut Cx) -> Result<()> {
    shape_fixture_wrong_version(cx, hook_value(Arc::new(AcceptOnNoDiagnosticsHook)))
}

fn conformance_discard_on_diagnostic_prefix_hook(cx: &mut Cx) -> Result<()> {
    shape_fixture_wrong_version(
        cx,
        hook_value(Arc::new(DiscardOnDiagnosticPrefixHook::new("shape-table:"))),
    )
}

fn conformance_venn_shape_set(cx: &mut Cx) -> Result<()> {
    let value = cx.factory().opaque(Arc::new(VennShapeSet::new(vec![(
        Symbol::new("any"),
        Arc::new(AnyShape),
    )])))?;
    shape_fixture_wrong_version(cx, value)
}

macro_rules! register_shape_citizen {
    ($install:ident, $conformance:ident, $symbol_text:literal, $symbol:expr, $arity:expr, $construct:ident) => {
        fn $install(linker: &mut Linker<'_>) -> Result<()> {
            register_shape_citizen_class(linker, $symbol, $construct)
        }

        sim_citizen::inventory::submit! {
            sim_citizen::CitizenInfo {
                symbol: $symbol_text,
                version: 1,
                crate_name: env!("CARGO_PKG_NAME"),
                arity: $arity,
                install: $install,
                conformance: $conformance,
            }
        }
    };
}

register_shape_citizen!(
    install_any_shape_citizen,
    conformance_any_shape,
    "shape/Any",
    any_shape_class_symbol(),
    0,
    construct_any_shape
);
register_shape_citizen!(
    install_exact_expr_shape_citizen,
    conformance_exact_expr_shape,
    "shape/ExactExpr",
    exact_expr_shape_class_symbol(),
    1,
    construct_exact_expr_shape
);
register_shape_citizen!(
    install_expr_kind_shape_citizen,
    conformance_expr_kind_shape,
    "shape/ExprKind",
    expr_kind_shape_class_symbol(),
    1,
    construct_expr_kind_shape
);
register_shape_citizen!(
    install_class_shape_citizen,
    conformance_class_shape,
    "shape/Class",
    class_shape_class_symbol(),
    1,
    construct_class_shape
);
register_shape_citizen!(
    install_list_shape_citizen,
    conformance_list_shape,
    "shape/List",
    list_shape_class_symbol(),
    2,
    construct_list_shape
);
register_shape_citizen!(
    install_table_shape_citizen,
    conformance_table_shape,
    "shape/Table",
    table_shape_class_symbol(),
    2,
    construct_table_shape
);
register_shape_citizen!(
    install_or_shape_citizen,
    conformance_or_shape,
    "shape/Or",
    or_shape_class_symbol(),
    2,
    construct_or_shape
);
register_shape_citizen!(
    install_and_shape_citizen,
    conformance_and_shape,
    "shape/And",
    and_shape_class_symbol(),
    1,
    construct_and_shape
);
register_shape_citizen!(
    install_not_shape_citizen,
    conformance_not_shape,
    "shape/Not",
    not_shape_class_symbol(),
    1,
    construct_not_shape
);
register_shape_citizen!(
    install_repeat_shape_citizen,
    conformance_repeat_shape,
    "shape/Repeat",
    repeat_shape_class_symbol(),
    3,
    construct_repeat_shape
);
register_shape_citizen!(
    install_shape_defs_citizen,
    conformance_shape_defs,
    "shape/Defs",
    shape_defs_class_symbol(),
    2,
    construct_shape_defs
);
register_shape_citizen!(
    install_shape_def_ref_citizen,
    conformance_shape_def_ref,
    "shape/Ref",
    shape_def_ref_class_symbol(),
    1,
    construct_shape_def_ref
);
register_shape_citizen!(
    install_hooked_shape_citizen,
    conformance_hooked_shape,
    "shape/Hooked",
    hooked_shape_class_symbol(),
    2,
    construct_hooked_shape
);
register_shape_citizen!(
    install_trace_mark_hook_citizen,
    conformance_trace_mark_hook,
    "shape/TraceMarkHook",
    crate::trace_mark_hook_class_symbol(),
    0,
    construct_trace_mark_hook
);
register_shape_citizen!(
    install_score_floor_hook_citizen,
    conformance_score_floor_hook,
    "shape/ScoreFloorHook",
    crate::score_floor_hook_class_symbol(),
    1,
    construct_score_floor_hook
);
register_shape_citizen!(
    install_accept_on_no_diagnostics_hook_citizen,
    conformance_accept_on_no_diagnostics_hook,
    "shape/AcceptOnNoDiagnosticsHook",
    crate::accept_on_no_diagnostics_hook_class_symbol(),
    0,
    construct_accept_on_no_diagnostics_hook
);
register_shape_citizen!(
    install_discard_on_diagnostic_prefix_hook_citizen,
    conformance_discard_on_diagnostic_prefix_hook,
    "shape/DiscardOnDiagnosticPrefixHook",
    crate::discard_on_diagnostic_prefix_hook_class_symbol(),
    1,
    construct_discard_on_diagnostic_prefix_hook
);
register_shape_citizen!(
    install_venn_shape_set_citizen,
    conformance_venn_shape_set,
    "shape/Venn",
    venn_shape_set_class_symbol(),
    1,
    construct_venn_shape_set
);
```