///|
/// Exported JavaScript boundary for canonical v2 problem files.
pub fn solve_json(input : String, algorithm : String, budget : Int) -> String {
try {
let problem = @scheduling.import_rcpsp_problem(input)
let result = match algorithm {
"from-input" =>
@scheduling.solve_rcpsp_request(@scheduling.import_rcpsp_request(input))
"stable-topological" =>
@scheduling.solve_rcpsp(
problem,
@scheduling.RcpspAlgorithm::StableTopological,
)
"critical-path" =>
@scheduling.solve_rcpsp(
problem,
@scheduling.RcpspAlgorithm::CriticalPath,
)
"recovery-heuristic" =>
@scheduling.solve_rcpsp(
problem,
@scheduling.RcpspAlgorithm::RecoveryHeuristic,
)
"budgeted-local-search" => @scheduling.optimize_rcpsp(problem, budget)
_ =>
raise @scheduling.SchedulingError::InvalidConstraint(
"unknown RCPSP algorithm",
)
}
@scheduling.export_rcpsp_solution(result)
} catch {
@scheduling.SchedulingError::InvalidTask(message)
| @scheduling.SchedulingError::InvalidResource(message)
| @scheduling.SchedulingError::InvalidDependency(message)
| @scheduling.SchedulingError::InvalidConstraint(message)
| @scheduling.SchedulingError::InvalidSchedule(message) => {
let escaped = @json.to_json(message).stringify()
"{\"error\":\{escaped}}"
}
error => {
let message = @json.to_json(error.to_string()).stringify()
"{\"error\":\{message}}"
}
}
}
///|
/// External candidate validation uses the same MoonBit constraint checker.
pub fn validate_json(problem_input : String, solution_input : String) -> String {
try {
let problem = @scheduling.import_rcpsp_problem(problem_input)
let _ = @scheduling.import_rcpsp_solution(problem, solution_input)
"{\"ok\":true}"
} catch {
@scheduling.SchedulingError::InvalidTask(message)
| @scheduling.SchedulingError::InvalidResource(message)
| @scheduling.SchedulingError::InvalidDependency(message)
| @scheduling.SchedulingError::InvalidConstraint(message)
| @scheduling.SchedulingError::InvalidSchedule(message) => {
let escaped = @json.to_json(message).stringify()
"{\"ok\":false,\"error\":\{escaped}}"
}
error => {
let message = @json.to_json(error.to_string()).stringify()
"{\"ok\":false,\"error\":\{message}}"
}
}
}
///|
fn main {
}