- src/types.hpp: complete UCWM type system in C++20 — 19 enums, 11 facet data types, all core structs (CanonicalObject, Constraint, Facet, GateSignal, WorldState, etc.) with full JSON round-trip serialization - src/main.cpp: smoke test — constructs apple-problem WorldState by hand, serializes to JSON - tests/test_types.cpp: 19 tests, 123 assertions, all passing - CMakeLists.txt: CMake + CPM build with nlohmann/json, spdlog, Catch2 - schemas/: JSON Schema contracts for all UCWM data types - gates/, specialists/, resolver/, synthesis/: language-agnostic interface contracts and domain specs for all pipeline layers - docs/: architecture, vocabulary, decision matrices, roadmap (6 phases, 28 sprints), sprint_001, implementation_constraints Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
133 lines
3.4 KiB
Markdown
133 lines
3.4 KiB
Markdown
# Quantity Specialist
|
|
|
|
**specialist_id:** `quantity`
|
|
**trigger_gates:** `has_quantity`, `is_math`
|
|
|
|
---
|
|
|
|
## Responsibility
|
|
|
|
The quantity specialist extracts numeric values, attaches QuantityFacets to quantity objects, and emits arithmetic and comparison constraints. When arithmetic can be resolved deterministically, it resolves it. When resolution requires a solver, it emits a structured constraint for the resolver.
|
|
|
|
---
|
|
|
|
## Manifest
|
|
|
|
```
|
|
declared_facet_kinds:
|
|
- quantity
|
|
|
|
declared_constraint_types:
|
|
- quantity_equals
|
|
- quantity_sum
|
|
- quantity_difference
|
|
- quantity_product
|
|
- quantity_quotient
|
|
- quantity_greater
|
|
- quantity_less
|
|
- quantity_at_least
|
|
- quantity_at_most
|
|
- quantity_bound
|
|
|
|
budget_caps:
|
|
max_objects_proposed: 6
|
|
max_facets_emitted: 6
|
|
max_constraints_emitted: 10
|
|
max_merges: 0
|
|
max_splits: 0
|
|
```
|
|
|
|
---
|
|
|
|
## Output: QuantityFacet
|
|
|
|
Attach to any object of kind `quantity`.
|
|
|
|
```
|
|
QuantityFacet fields used:
|
|
- value: number or symbolic expression
|
|
- unit: string (apples, dollars, meters, etc.)
|
|
- is_exact: true/false
|
|
- derived_from_refs: quantity object IDs this was computed from
|
|
```
|
|
|
|
---
|
|
|
|
## Output: Constraints
|
|
|
|
### `quantity_equals(Q_result, expression)`
|
|
|
|
Emit when a quantity is defined as equal to an expression.
|
|
|
|
```
|
|
{
|
|
"constraint_type": "quantity_equals",
|
|
"argument_refs": ["Q_alice_final", "Q_expr_5_minus_2"],
|
|
"expression": "quantity(Q_alice_final) = quantity(Q1) - quantity(Q2)",
|
|
"strength": "hard"
|
|
}
|
|
```
|
|
|
|
### `quantity_difference(Q_result, Q_minuend, Q_subtrahend)`
|
|
|
|
Preferred form when the specific operation is subtraction.
|
|
|
|
```
|
|
argument_refs order: [result, minuend, subtrahend]
|
|
```
|
|
|
|
### `quantity_sum(Q_result, Q_addend1, Q_addend2, ...)`
|
|
|
|
Result equals the sum of all argument quantities.
|
|
|
|
### `quantity_greater(Q_a, Q_b)`
|
|
|
|
Q_a > Q_b.
|
|
|
|
### `quantity_less(Q_a, Q_b)`
|
|
|
|
Q_a < Q_b.
|
|
|
|
---
|
|
|
|
## Arithmetic resolution
|
|
|
|
When all inputs to an arithmetic constraint are exact numeric values, the quantity specialist SHOULD resolve the arithmetic inline and set the result quantity's `value` directly.
|
|
|
|
```
|
|
if quantity_difference(Q_result, Q1, Q2):
|
|
if Q1.value is exact numeric AND Q2.value is exact numeric:
|
|
Q_result.value = Q1.value - Q2.value
|
|
Q_result.is_exact = true
|
|
mark constraint as resolved
|
|
else:
|
|
emit constraint with status = unresolved
|
|
resolver handles it
|
|
```
|
|
|
|
This avoids unnecessary round-trips through the resolver for simple arithmetic.
|
|
|
|
---
|
|
|
|
## Unit tracking
|
|
|
|
Units must be tracked and propagated. Emitting a `quantity_difference` constraint without units is not sufficient — the result unit must be declared or inferred.
|
|
|
|
Rules:
|
|
- Same unit on both operands: result inherits unit
|
|
- Different units on operands: emit a `quantity_bound` constraint marking the result as unit-ambiguous until a converter is applied
|
|
- Unitless operands: result is unitless
|
|
|
|
---
|
|
|
|
## Contract test requirements
|
|
|
|
- Given `Alice had 5 apples. She gave Bob 2 apples.`:
|
|
- Must emit Q1 with value=5, unit="apples"
|
|
- Must emit Q2 with value=2, unit="apples"
|
|
- Must emit `quantity_difference(Q_alice_final, Q1, Q2)` or `quantity_equals(Q_alice_final, "5-2")`
|
|
- Must set Q_alice_final.value = 3 (inline resolution)
|
|
- Must not emit temporal or entity constraints
|
|
- All quantity facets must have `unit` set or explicitly `"unitless"`
|
|
- All emitted constraints must have `source_module: quantity`
|