| from __future__ import annotations |
|
|
| import json |
| from pathlib import Path |
| from typing import Optional |
|
|
| import typer |
|
|
| from core.models import CompileInput, DecisionVars, Ontology, Resident, RuleIR |
| from solver.builder import build_model |
| from nlp.parser import derive_cohorts_from_text |
|
|
|
|
| app = typer.Typer(help="Compile NL rules + ontology to OR-Tools decision vars (POC)") |
|
|
|
|
| @app.command() |
| def compile( |
| ontology_json: Path = typer.Argument(..., help="Path to ontology.json"), |
| rules_json: Optional[Path] = typer.Argument(None, help="Path to rules.json (RuleIR list)"), |
| out_json: Path = typer.Option(Path("decision_vars.json"), help="Output path for variable names"), |
| report_md: Path = typer.Option(Path("compile_report.md"), help="Compile report output"), |
| cohorts_text: Optional[Path] = typer.Option(None, help="Optional free text to derive cohorts"), |
| ): |
| onto = Ontology.model_validate_json(ontology_json.read_text()) |
| rules = [] |
| if rules_json and rules_json.exists(): |
| rules = [RuleIR.model_validate(obj) for obj in json.loads(rules_json.read_text())] |
| cohorts = {} |
| if cohorts_text and cohorts_text.exists(): |
| cohorts = derive_cohorts_from_text(cohorts_text.read_text(), [r.id for r in onto.residents]) |
|
|
| ci = CompileInput(ontology=onto, rules=rules, cohorts=cohorts) |
|
|
| model, dv, var_map, report = build_model(ci) |
|
|
| out = {"x_vars": dv.x_vars, "count": len(dv.x_vars), "cohorts": cohorts} |
| out_json.write_text(json.dumps(out, indent=2)) |
| report_md.write_text( |
| f"# Compile report\n\n" |
| f"Residents: {report.num_residents}\n\n" |
| f"Blocks: {report.num_blocks}\n\n" |
| f"Rotations: {report.num_rotations}\n\n" |
| f"x-vars: {report.num_x_vars}\n\n" |
| f"aux-vars: {report.num_aux_vars}\n" |
| ) |
| typer.echo(f"Wrote {len(dv.x_vars)} decision variables to {out_json}; report to {report_md}") |
|
|
|
|
| if __name__ == "__main__": |
| app() |
|
|
|
|
|
|