///|
/// Main Entrypoint for moonbit-auction Demo & Benchmark Execution.
fn main {
println(
"=========================================================================",
)
println(
"🚀 moonbit-auction: Market Mechanism Design & Simulation Framework",
)
println(
"=========================================================================\n",
)
// 1. Single Item Auctions Demonstration
println("--- [1] Single-Item Auction Simulation (Vickrey vs First-Price) ---")
let item = @types.Item::new(
"item-101",
"H100 GPU Server Node",
reserve_price=500.0,
)
let vickrey = @single_item.VickreyAuction::new(item)
let _ = vickrey.submit_bid("bidder-Alice", 1200.0)
let _ = vickrey.submit_bid("bidder-Bob", 1500.0)
let _ = vickrey.submit_bid("bidder-Charlie", 1350.0)
match vickrey.finalize() {
Ok(outcome) => println(@analytics.explain_allocation(outcome))
Err(e) => println("Error running Vickrey auction: \{e}")
}
// 2. Combinatorial Package Bidding WDP Solver Demonstration
println("\n--- [2] Combinatorial XOR Bundle Auction (WDP Solver) ---")
let bundle_items = ["cloud-vm", "storage-bucket", "cdn-bandwidth"]
let comb_auction = @multi_item.CombinatorialAuction::new(
bundle_items,
valuation_type=@types.ValuationType::XOR,
)
let _ = comb_auction.submit_bundle_bid(
"corp-Alpha",
["cloud-vm", "storage-bucket"],
950.0,
)
let _ = comb_auction.submit_bundle_bid(
"corp-Beta",
["storage-bucket", "cdn-bandwidth"],
400.0,
)
let _ = comb_auction.submit_bundle_bid("corp-Gamma", ["cdn-bandwidth"], 200.0)
match comb_auction.solve_wdp() {
Ok(winning_bundles) => {
println("WDP Optimal Non-Overlapping Winners:")
let mut total_rev = 0.0
for bundle in winning_bundles {
println(
" - Bidder: " +
bundle.bidder_id +
" | Amount: " +
bundle.bid_amount.to_string(),
)
total_rev = total_rev + bundle.bid_amount
}
println("Total Package Revenue: \{total_rev}")
}
Err(e) => println("Error solving WDP: \{e}")
}
// 3. Ad Slot Keyword Auction Demonstration (GSP vs VCG)
println("\n--- [3] Search Ad Keyword Auction (GSP Position Pricing) ---")
let slots = [
@ad_auction.AdSlot::new("top-slot", 1, 0.25),
@ad_auction.AdSlot::new("sidebar-slot", 2, 0.10),
]
let gsp = @ad_auction.GspAuction::new(slots, reserve_price=1.0)
let _ = gsp.submit_bid("brand-TechCorp", 8.0, quality_score=2.0)
let _ = gsp.submit_bid("brand-FastLogistics", 6.0, quality_score=1.5)
let _ = gsp.submit_bid("brand-CloudData", 4.0, quality_score=1.0)
match gsp.finalize() {
Ok(outcome) => println(@analytics.explain_allocation(outcome))
Err(e) => println("Error running GSP auction: \{e}")
}
// 4. Two-Sided Matching (Gale-Shapley Deferred Acceptance)
println("\n--- [4] Gale-Shapley Stable Deferred Acceptance Matching ---")
let da = @matching.DeferredAcceptance::new()
da.add_proposer("procurement-buyer-1", ["vendor-X", "vendor-Y"])
da.add_proposer("procurement-buyer-2", ["vendor-X", "vendor-Y"])
da.add_receiver(
"vendor-X",
["procurement-buyer-2", "procurement-buyer-1"],
capacity=1,
)
da.add_receiver(
"vendor-Y",
["procurement-buyer-1", "procurement-buyer-2"],
capacity=1,
)
let matches = da.solve()
println("Stable Matching Assignments:")
matches.each(fn(buyer, seller) { println(" - \{buyer} <===> \{seller}") })
// 5. Market Simulator & Analytics Report Generation
println("\n--- [5] Event-Driven Market Simulator & Welfare Report ---")
let sim_items = [
@types.Item::new("compute-node", "Edge Node", reserve_price=100.0),
]
let sim_agents = [
@strategy.BiddingAgent::new(
"agent-1",
"Agent 1",
300.0,
strategy=@strategy.StrategyType::Truthful,
),
@strategy.BiddingAgent::new(
"agent-2",
"Agent 2",
280.0,
strategy=@strategy.StrategyType::Shaded(0.9),
),
@strategy.BiddingAgent::new(
"agent-3",
"Agent 3",
250.0,
strategy=@strategy.StrategyType::AdaptiveEpsilonGreedy(0.1, 0.05),
),
]
let simulator = @simulation.MarketSimulator::new(
sim_items,
sim_agents,
mechanism=@simulation.MarketMechanismType::Vickrey,
)
let outcomes = simulator.run_simulation(5)
let metrics = @analytics.analyze_outcomes(outcomes)
println(@analytics.generate_summary_report(metrics))
// 6. Reproducible benchmark CLI output. Logical steps are used instead of
// wall-clock time so results remain comparable across CI runners.
println("\n--- [6] Reproducible Benchmark Suite ---")
let suite = @analytics.BenchmarkSuite::new()
suite.add_case(@analytics.BenchmarkCase::new("small", 8, 4))
suite.add_case(@analytics.BenchmarkCase::new("medium", 32, 8))
let benchmark_records = suite.run()
for record in benchmark_records {
println(
" " +
record.summary() +
" digest_length=" +
record.workload_digest.length().to_string(),
)
}
let dashboard = @analytics.benchmark_dashboard(benchmark_records)
println(@analytics.KpiDashboard::to_markdown(dashboard))
println(
"=========================================================================",
)
println("✅ Market Simulation Completed Successfully.")
println(
"=========================================================================",
)
}