hyf

Context-aware query service for Radroots
git clone https://radroots.dev/git/hyf.git
Log | Files | Refs | README | LICENSE

commit 5747fc98cf717c5064d6acc1e403baa444466053
parent 115d11a98470f60f186a87f2474d082bc8500bdb
Author: triesap <tyson@radroots.org>
Date:   Mon, 21 Sep 2026 13:00:48 +0000

core: add demand line and constraint types

Diffstat:
Asrc/hyf_core/domain/demand.mojo | 70++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Mtests/test_domain.mojo | 28++++++++++++++++++++++++++++
2 files changed, 98 insertions(+), 0 deletions(-)

diff --git a/src/hyf_core/domain/demand.mojo b/src/hyf_core/domain/demand.mojo @@ -0,0 +1,70 @@ +from std.collections import List, Optional + +from hyf_core.domain.product import ProductRef + + +@fieldwise_init +struct Condition(Copyable, Movable): + var kind: String + var strength: String + var value: Optional[String] + + +@fieldwise_init +struct DemandLine(Copyable, Movable): + var line_id: String + var product: ProductRef + var quantity_state: String + var quantity_value: Int + var quantity_scale: Int + var unit: String + var conditions: List[Condition] + + +def condition(kind: String, strength: String, value: Optional[String]) raises -> Condition: + if kind.strip() == "": + raise Error("condition kind must not be empty") + var strengths = ["mandatory", "preferred", "excluded", "permitted"] + var known = False + for candidate in strengths: + if candidate == strength: + known = True + if not known: + raise Error("unknown condition strength: " + strength) + if strength != "excluded" and not value: + raise Error("non-excluded condition requires a value") + return Condition(kind=String(kind), strength=String(strength), value=value.copy()) + + +def demand_line( + line_id: String, + product: ProductRef, + quantity_state: String, + quantity_value: Int, + quantity_scale: Int, + conditions: List[Condition], +) raises -> DemandLine: + if line_id.strip() == "": + raise Error("demand line requires an id") + if quantity_state != "known" and quantity_state != "unknown": + raise Error("demand quantity state must be 'known' or 'unknown'") + var copied = List[Condition]() + for entry in conditions: + copied.append(entry.copy()) + return DemandLine( + line_id=String(line_id), + product=product.copy(), + quantity_state=String(quantity_state), + quantity_value=quantity_value, + quantity_scale=quantity_scale, + unit="kg", + conditions=copied^, + ) + + +def condition_is_exclusion(value: Condition) -> Bool: + return value.strength == "excluded" + + +def missing_information_is_prohibition() -> Bool: + return False diff --git a/tests/test_domain.mojo b/tests/test_domain.mojo @@ -421,3 +421,31 @@ def test_clarification_refines_without_overwriting_original() raises: assert_equal(refined.value.value(), "60") assert_true(not clarification_is_stale(evidence, "r2")) assert_true(clarification_is_stale(evidence, "r3")) + + +from hyf_core.domain.demand import ( + Condition, + DemandLine, + condition, + condition_is_exclusion, + demand_line, + missing_information_is_prohibition, +) + + +def test_demand_lines_and_condition_strength() raises: + var tomatoes = resolved_product("tomatoes", "tomato") + var lines = List[DemandLine]() + var conditions_a = List[Condition]() + conditions_a.append(condition("fulfillment", "mandatory", Optional[String]("delivery"))) + conditions_a.append(condition("fulfillment_excluded", "excluded", Optional[String]("pickup"))) + lines.append(demand_line("l1", tomatoes, "known", 25, 0, conditions_a)) + var conditions_b = List[Condition]() + conditions_b.append(condition("grade", "permitted", Optional[String]("seconds"))) + lines.append(demand_line("l2", tomatoes, "unknown", 0, 0, conditions_b)) + assert_equal(len(lines), 2) + assert_true(condition_is_exclusion(lines[0].conditions[1])) + assert_true(not condition_is_exclusion(lines[0].conditions[0])) + assert_true(not missing_information_is_prohibition()) + with assert_raises(): + _ = condition("grade", "maybe", Optional[String]("x"))