Sprint 1: project skeleton, type system, and all architecture specs
- 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>
This commit is contained in:
132
specialists/quantity.md
Normal file
132
specialists/quantity.md
Normal file
@@ -0,0 +1,132 @@
|
||||
# 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`
|
||||
Reference in New Issue
Block a user