Introduce a principled mechanism for registering external pure functions
callable from bind expressions during grounding. This is the foundation
for aggregation and other extension use-cases.
- Add FunctionRegistry, ExtensionFunction trait, EvalContext, and
supporting types in new function_registry module
- Add ArithExpr::Call variant and ArithError::{UnknownFunction,FunctionError}
- Add eval_with_context() on ArithExpr and ArithConstraint, threading
EvalContext through the grounding call chain
- Update parser to emit Call nodes for unknown names in expression position
- Add validation of Call nodes against registry (existence + arity)
- Add function_registry field to PipelineContext and PrepareOptions
- Zero existing behaviour changes: programs without extension functions
behave identically (1827 existing tests pass unchanged)
Co-Authored-By: Claude Opus 4.6 noreply@anthropic.com
fix: remove redundant Arity::describe(), fix pluralization, add test coverage
- Remove Arity::describe() in favor of the identical Display impl
- Fix "expects N arguments" → "expects N argument(s)" for grammatical correctness
- Add integration tests: range arity, non-numeric return, nested calls,
call in body predicate argument, and zero-arg function
- Add unit tests for ArithExpr::Call evaluation paths
- Apply cargo fmt to touched files
Co-Authored-By: Claude Opus 4.6 noreply@anthropic.com
test: add extension function test coverage for non-integer returns, e2e reasoning, multi-function
- Add end-to-end reasoning test through reason_with_options() with extension functions
- Add Decimal return type test (HalfFunction)
- Add Float return type test (SqrtFunction with FiniteFloat)
- Add multiple extension functions in one theory test
- Add TODO comment in query/mod.rs for function_registry threading
Co-Authored-By: Claude Opus 4.6 noreply@anthropic.com
fix: struct initialisation
Introduce a principled mechanism for registering external pure functions
callable from `bind` expressions during grounding. This is the foundation
for aggregation and other extension use-cases.
- Add FunctionRegistry, ExtensionFunction trait, EvalContext, and
supporting types in new function_registry module
- Add ArithExpr::Call variant and ArithError::{UnknownFunction,FunctionError}
- Add eval_with_context() on ArithExpr and ArithConstraint, threading
EvalContext through the grounding call chain
- Update parser to emit Call nodes for unknown names in expression position
- Add validation of Call nodes against registry (existence + arity)
- Add function_registry field to PipelineContext and PrepareOptions
- Zero existing behaviour changes: programs without extension functions
behave identically (1827 existing tests pass unchanged)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
fix: remove redundant Arity::describe(), fix pluralization, add test coverage
- Remove Arity::describe() in favor of the identical Display impl
- Fix "expects N arguments" → "expects N argument(s)" for grammatical correctness
- Add integration tests: range arity, non-numeric return, nested calls,
call in body predicate argument, and zero-arg function
- Add unit tests for ArithExpr::Call evaluation paths
- Apply cargo fmt to touched files
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
test: add extension function test coverage for non-integer returns, e2e reasoning, multi-function
- Add end-to-end reasoning test through reason_with_options() with extension functions
- Add Decimal return type test (HalfFunction)
- Add Float return type test (SqrtFunction with FiniteFloat)
- Add multiple extension functions in one theory test
- Add TODO comment in query/mod.rs for function_registry threading
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
fix: struct initialisation