// moonbit-4d-schedule - CLI Entrypoint & Demonstration Solver
///|
pub fn create_sample_building_project() -> @types.ScheduleProject {
let cal = @types.WorkCalendar::default_standard()
let elements : Array[@types.BimElement] = [
{
guid: "GUID_FND_01",
name: "Raft Foundation F1",
category: Foundation,
level: "B1",
zone: "Zone A",
bounds: {
min_point: { x: 0.0, y: 0.0, z: -3.0 },
max_point: { x: 20.0, y: 30.0, z: 0.0 },
},
volume: 1800.0,
},
{
guid: "GUID_COL_B1_01",
name: "Column Group C_B1",
category: Column,
level: "B1",
zone: "Zone A",
bounds: {
min_point: { x: 0.0, y: 0.0, z: 0.0 },
max_point: { x: 20.0, y: 30.0, z: 3.5 },
},
volume: 120.0,
},
{
guid: "GUID_SLAB_L1_01",
name: "Floor Slab S_L1",
category: Slab,
level: "L1",
zone: "Zone A",
bounds: {
min_point: { x: 0.0, y: 0.0, z: 3.5 },
max_point: { x: 20.0, y: 30.0, z: 3.8 },
},
volume: 180.0,
},
{
guid: "GUID_COL_L1_01",
name: "Column Group C_L1",
category: Column,
level: "L1",
zone: "Zone A",
bounds: {
min_point: { x: 0.0, y: 0.0, z: 3.8 },
max_point: { x: 20.0, y: 30.0, z: 7.3 },
},
volume: 120.0,
},
{
guid: "GUID_SLAB_L2_01",
name: "Roof Slab S_L2",
category: Roof,
level: "L2",
zone: "Zone A",
bounds: {
min_point: { x: 0.0, y: 0.0, z: 7.3 },
max_point: { x: 20.0, y: 30.0, z: 7.6 },
},
volume: 180.0,
},
{
guid: "GUID_MEP_01",
name: "HVAC & Electrical Riser",
category: MEP,
level: "L1-L2",
zone: "Core",
bounds: {
min_point: { x: 8.0, y: 12.0, z: 0.0 },
max_point: { x: 12.0, y: 18.0, z: 7.6 },
},
volume: 45.0,
},
]
let activities : Array[@types.Activity] = [
{
id: "ACT_01",
code: "100",
name: "Site Preparation & Excavation",
duration: 10.0,
optimistic_duration: 8.0,
pessimistic_duration: 14.0,
calendar_id: cal.id,
constraint: { constraint_type: AsSoonAsPossible, target_date: None },
predecessors: [],
element_ids: ["GUID_FND_01"],
},
{
id: "ACT_02",
code: "110",
name: "Cast Raft Foundation",
duration: 12.0,
optimistic_duration: 9.0,
pessimistic_duration: 18.0,
calendar_id: cal.id,
constraint: { constraint_type: AsSoonAsPossible, target_date: None },
predecessors: [{ activity_id: "ACT_01", dep_type: FS, lag_days: 0.0 }],
element_ids: ["GUID_FND_01"],
},
{
id: "ACT_03",
code: "200",
name: "Erect B1 Columns & Shearing Walls",
duration: 15.0,
optimistic_duration: 12.0,
pessimistic_duration: 21.0,
calendar_id: cal.id,
constraint: { constraint_type: AsSoonAsPossible, target_date: None },
predecessors: [{ activity_id: "ACT_02", dep_type: FS, lag_days: 0.0 }],
element_ids: ["GUID_COL_B1_01"],
},
{
id: "ACT_04",
code: "210",
name: "Pour L1 Floor Slab",
duration: 10.0,
optimistic_duration: 8.0,
pessimistic_duration: 14.0,
calendar_id: cal.id,
constraint: { constraint_type: AsSoonAsPossible, target_date: None },
predecessors: [{ activity_id: "ACT_03", dep_type: FS, lag_days: 0.0 }],
element_ids: ["GUID_SLAB_L1_01"],
},
{
id: "ACT_05",
code: "300",
name: "Erect L1 Columns",
duration: 14.0,
optimistic_duration: 10.0,
pessimistic_duration: 20.0,
calendar_id: cal.id,
constraint: { constraint_type: AsSoonAsPossible, target_date: None },
predecessors: [{ activity_id: "ACT_04", dep_type: FS, lag_days: 0.0 }],
element_ids: ["GUID_COL_L1_01"],
},
{
id: "ACT_06",
code: "310",
name: "Pour L2 Roof Slab",
duration: 10.0,
optimistic_duration: 7.0,
pessimistic_duration: 15.0,
calendar_id: cal.id,
constraint: { constraint_type: AsSoonAsPossible, target_date: None },
predecessors: [{ activity_id: "ACT_05", dep_type: FS, lag_days: 0.0 }],
element_ids: ["GUID_SLAB_L2_01"],
},
{
id: "ACT_07",
code: "400",
name: "MEP Rough-in & Ducting",
duration: 18.0,
optimistic_duration: 14.0,
pessimistic_duration: 26.0,
calendar_id: cal.id,
constraint: { constraint_type: AsSoonAsPossible, target_date: None },
predecessors: [{ activity_id: "ACT_04", dep_type: SS, lag_days: 5.0 }],
element_ids: ["GUID_MEP_01"],
},
]
let resources : Array[@types.Resource] = [
{
id: "RES_LABOR",
code: "LAB-01",
name: "Steel Fixers & Carpenters",
kind: Labor,
unit: "Man-days",
max_capacity: 25.0,
cost_per_unit: 350.0,
},
{
id: "RES_CRANE",
code: "EQP-01",
name: "Tower Crane 50t",
kind: Equipment,
unit: "Hours",
max_capacity: 10.0,
cost_per_unit: 1200.0,
},
]
let demands : Array[@types.ResourceDemand] = [
{ activity_id: "ACT_01", resource_id: "RES_CRANE", units_per_day: 8.0 },
{ activity_id: "ACT_02", resource_id: "RES_LABOR", units_per_day: 20.0 },
{ activity_id: "ACT_03", resource_id: "RES_LABOR", units_per_day: 18.0 },
{ activity_id: "ACT_03", resource_id: "RES_CRANE", units_per_day: 6.0 },
{ activity_id: "ACT_04", resource_id: "RES_LABOR", units_per_day: 15.0 },
{ activity_id: "ACT_05", resource_id: "RES_LABOR", units_per_day: 18.0 },
{ activity_id: "ACT_06", resource_id: "RES_LABOR", units_per_day: 15.0 },
{ activity_id: "ACT_07", resource_id: "RES_LABOR", units_per_day: 10.0 },
]
{
id: "PROJ_4D_DEMO",
name: "4D BIM Commercial Building Schedule",
start_date: { year: 2026, month: 9, day: 1 },
calendars: [cal],
activities,
elements,
resources,
demands,
}
}
///|
pub fn run_cli_demo() -> Unit {
let proj = create_sample_building_project()
println("=================================================================")
println(" moonbit-4d-schedule Engine - Smart Construction 4D BIM Solver")
println("=================================================================")
println("Project: " + proj.name + " (" + proj.id + ")")
println("Start Date: " + proj.start_date.to_iso_string())
println("Activities: " + proj.activities.length().to_string())
println("BIM Elements: " + proj.elements.length().to_string())
println("")
let graph = match @graph.NetworkGraph::build(proj.activities) {
Ok(g) => g
Err(_) => return ()
}
let cpm = match @graph.solve_cpm(graph) {
Ok(c) => c
Err(_) => return ()
}
println("[CPM Schedule Analysis]")
println(
"Total Project Duration: " + cpm.project_duration.to_string() + " Days",
)
println("Critical Path Count: " + cpm.critical_path.length().to_string())
for act_id in proj.activities {
let fl = cpm.floats.get(act_id.id).unwrap()
let crit_tag = if fl.is_critical { " [CRITICAL]" } else { "" }
println(
" Activity " +
act_id.code +
": " +
act_id.name +
" -> ES=" +
fl.early_start.to_string() +
" EF=" +
fl.early_finish.to_string() +
" TF=" +
fl.total_float.to_string() +
crit_tag,
)
}
println("")
println("[PERT 3-Estimate Probabilistic Analysis]")
let pert_res = match @pert.analyze_pert(proj.activities) {
Ok(p) => p
Err(_) => return ()
}
println(
"Expected Project Duration: " +
pert_res.expected_project_duration.to_string() +
" Days",
)
println(
"Total Variance (Critical Path): " + pert_res.total_variance.to_string(),
)
println("Standard Deviation: " + pert_res.total_std_dev.to_string() + " Days")
let target_d = pert_res.expected_project_duration + 5.0
let prob = @pert.calculate_completion_probability(pert_res, target_d)
println(
"Completion Probability by Day " +
target_d.to_string() +
": " +
(prob * 100.0).to_int().to_string() +
"%",
)
println("")
println("[Burgess-Killebrew Resource Leveling]")
let lev = @leveling.level_resource_burgess(
"RES_LABOR",
proj.activities,
proj.demands,
cpm,
)
println("Resource: Steel Fixers & Carpenters (RES_LABOR)")
println(
"Peak Demand (Before Leveling): " +
lev.initial_profile.max_demand.to_string(),
)
println(
"Peak Demand (After Leveling): " +
lev.leveled_profile.max_demand.to_string(),
)
println(
"Sum of Demand Squares Reduction: " +
(lev.sum_squares_reduction * 100.0).to_int().to_string() +
"%",
)
println("")
println("[4D BIM State Snapshot at Day 25]")
let snap = @bim4d.generate_4d_snapshot(proj, cpm, 25.0)
println("Timestamp: Day 25")
println(
"Overall Completion: " +
(snap.overall_completion * 100.0).to_int().to_string() +
"%",
)
println(
"Active BIM Elements in Progress: " + snap.active_activity_count.to_string(),
)
for elem_st in snap.elements {
println(
" Element " +
elem_st.guid +
": Status=" +
elem_st.status.to_color() +
" (" +
(elem_st.completion_ratio * 100.0).to_int().to_string() +
"%)",
)
}
println("")
println("[JSON Serialized Snapshot Payload Sample]")
let json_payload = @json.serialize_state_snapshot(snap)
println(json_payload)
println("=================================================================")
}
///|
fn main {
run_cli_demo()
}