complex_discount.iml

IML example from the CodeLogician agent skill.

(*
   --------------------------------------------------------------------------
   title: Complex Discount Calculation
   name: complex-discount
   description: Multiple overlapping discount rules with caps
   --------------------------------------------------------------------------
 
   Real-world TRICKY example: Complex Discount Calculation with Overlapping Rules
 
   THE TRICKY PROBLEM:
   Multiple discount rules can apply simultaneously, and their interaction is complex:
   1. Volume discount: >= 10 items get 10% off, >= 50 items get 20% off
   2. Loyalty program: Bronze 5% off, Silver 10% off, Gold 15% off
   3. Seasonal discount: 25% off during sale season
   4. Maximum discount cap: Total discount cannot exceed 40%
   5. Minimum purchase: Discounts only apply if total >= $50
 
   Question: How many distinct pricing scenarios are there? Are all combinations handled?
   WITHOUT decomposition: Very hard to enumerate all cases manually!
   WITH decomposition: Automatically reveals all 20+ distinct pricing regions!
 
   This demonstrates decomposition's power for:
   - Discovering hidden edge cases in complex business logic
   - Ensuring completeness (all cases covered)
   - Finding unexpected interactions between rules
*)
 
type loyalty_tier = None | Bronze | Silver | Gold
 
(* Helper: Calculate loyalty discount percentage *)
let loyalty_discount tier =
  match tier with
  | None -> 0
  | Bronze -> 5
  | Silver -> 10
  | Gold -> 15
 
(* Helper: Calculate volume discount percentage *)
let volume_discount quantity =
  if quantity >= 50 then 20
  else if quantity >= 10 then 10
  else 0
 
(* THE TRICKY FUNCTION: Multiple overlapping discount rules *)
let calculate_final_price base_price quantity tier is_sale_season =
  if base_price < 50 then
    (* No discounts if under minimum *)
    base_price
  else
    (* Calculate each discount component *)
    let vol_disc = volume_discount quantity in
    let loyalty_disc = loyalty_discount tier in
    let seasonal_disc = if is_sale_season then 25 else 0 in
 
    (* Sum all discounts *)
    let total_disc = vol_disc + loyalty_disc + seasonal_disc in
 
    (* Apply 40% cap *)
    let final_disc = if total_disc > 40 then 40 else total_disc in
 
    (* Calculate final price *)
    base_price - (base_price * final_disc / 100)
[@@decomp top ~basis:[[%id volume_discount]; [%id loyalty_discount]] ()]
 
(* VARIATION 1: What if we inline the helper functions?
   This will create MANY more regions as it expands all combinations!
*)
let calculate_final_price_expanded base_price quantity tier is_sale_season =
  if base_price < 50 then
    base_price
  else
    let vol_disc =
      if quantity >= 50 then 20
      else if quantity >= 10 then 10
      else 0
    in
    let loyalty_disc =
      match tier with
      | None -> 0
      | Bronze -> 5
      | Silver -> 10
      | Gold -> 15
    in
    let seasonal_disc = if is_sale_season then 25 else 0 in
    let total_disc = vol_disc + loyalty_disc + seasonal_disc in
    let final_disc = if total_disc > 40 then 40 else total_disc in
    base_price - (base_price * final_disc / 100)
[@@decomp top ()]
 
(* VARIATION 2: Using ~prune to focus analysis
   This removes infeasible regions for cleaner analysis
*)
let calculate_final_price_valid base_price quantity tier is_sale_season =
  if base_price < 50 then
    base_price
  else
    let vol_disc = volume_discount quantity in
    let loyalty_disc = loyalty_discount tier in
    let seasonal_disc = if is_sale_season then 25 else 0 in
    let total_disc = vol_disc + loyalty_disc + seasonal_disc in
    let final_disc = if total_disc > 40 then 40 else total_disc in
    base_price - (base_price * final_disc / 100)
[@@decomp top ~prune:true ~basis:[[%id volume_discount]; [%id loyalty_discount]] ()]