- 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>
3.4 KiB
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_boundconstraint 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)orquantity_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
unitset or explicitly"unitless" - All emitted constraints must have
source_module: quantity