{
  "tool": "api_abstraction_map",
  "args": {
    "sources": [
      {
        "fileName": "before.bosatsu",
        "source": "package Yichus/Examples/OrderAllocation\n\n# An order-allocation component used by cart, checkout, and support.\n\nexport (\n  Stock(),\n  Allocation(),\n  CartPreview(),\n  CheckoutDecision(),\n  ReplacementStatus(),\n  SupportReplacement(),\n  allocation_plan,\n  cart_preview,\n  checkout_order,\n  support_replacement,\n)\n\nstruct Stock(on_hand: Int, committed: Int, safety_stock: Int)\n\nstruct Allocation(\n  requested: Int,\n  allocated: Int,\n  backordered: Int,\n  remaining: Int,\n)\n\nstruct CartPreview(sku: String, allocation: Allocation, can_checkout: Bool)\n\nstruct CheckoutDecision(order_id: String, allocation: Allocation, accepted: Bool)\n\nenum ReplacementStatus:\n  Ready\n  PartiallyBackordered\n\nstruct SupportReplacement(\n  case_id: String,\n  allocation: Allocation,\n  status: ReplacementStatus,\n)\n\ndef nonnegative(value: Int) -> Int:\n  match cmp_Int(value, 0):\n    case LT: 0\n    case _: value\n\ndef min_int(left: Int, right: Int) -> Int:\n  match cmp_Int(left, right):\n    case LT: left\n    case _: right\n\ndef sellable_units(stock: Stock) -> Int:\n  Stock(on_hand, committed, safety_stock) = stock\n  nonnegative(nonnegative(on_hand).sub(nonnegative(committed)).sub(nonnegative(safety_stock)))\n\ndef allocation_plan(stock: Stock, requested: Int) -> Allocation:\n  Allocation(\n    nonnegative(requested),\n    min_int(nonnegative(requested), sellable_units(stock)),\n    nonnegative(requested).sub(min_int(nonnegative(requested), sellable_units(stock))),\n    sellable_units(stock).sub(min_int(nonnegative(requested), sellable_units(stock))),\n  )\n\ndef is_complete(allocation: Allocation) -> Bool:\n  Allocation(_, _, backordered, _) = allocation\n  eq_Int(backordered, 0)\n\ndef cart_preview(sku: String, stock: Stock, requested: Int) -> CartPreview:\n  allocation = Allocation(\n    nonnegative(requested),\n    min_int(nonnegative(requested), sellable_units(stock)),\n    nonnegative(requested).sub(min_int(nonnegative(requested), sellable_units(stock))),\n    sellable_units(stock).sub(min_int(nonnegative(requested), sellable_units(stock))),\n  )\n  CartPreview(sku, allocation, is_complete(allocation))\n\ndef checkout_order(order_id: String, stock: Stock, requested: Int) -> CheckoutDecision:\n  allocation = allocation_plan(stock, requested)\n  CheckoutDecision(order_id, allocation, is_complete(allocation))\n\ndef support_replacement(case_id: String, stock: Stock, requested: Int) -> SupportReplacement:\n  allocation = Allocation(\n    nonnegative(requested),\n    min_int(nonnegative(requested), sellable_units(stock)),\n    nonnegative(requested).sub(min_int(nonnegative(requested), sellable_units(stock))),\n    sellable_units(stock).sub(min_int(nonnegative(requested), sellable_units(stock))),\n  )\n  status = if is_complete(allocation): Ready\n  else: PartiallyBackordered\n  SupportReplacement(case_id, allocation, status)\n"
      }
    ]
  }
}
