use anyhow::Result;
use clap::Parser;
#[derive(Parser, Debug)]
pub struct Opts {
pub input: String,
#[arg(short, long)]
pub model: Option<String>,
#[arg(short, long)]
pub formula: Option<String>,
#[arg(long)]
pub formula_text: Option<String>,
}
pub async fn run(opts: &Opts) -> Result<()> {
let content = std::fs::read_to_string(&opts.input)?;
let models = modality_lang::parse_all_models_content_lalrpop(&content)
.map_err(|e| anyhow::anyhow!("Failed to parse models: {}", e))?;
let model = if let Some(model_name) = &opts.model {
models.into_iter()
.find(|m| m.name == *model_name)
.ok_or_else(|| anyhow::anyhow!("Model '{}' not found", model_name))?
} else {
models.into_iter()
.next()
.ok_or_else(|| anyhow::anyhow!("No models found in file"))?
};
let formula = if let Some(formula_name) = &opts.formula {
let formulas = modality_lang::parse_all_formulas_content_lalrpop(&content)
.map_err(|e| anyhow::anyhow!("Failed to parse formulas: {}", e))?;
formulas.into_iter()
.find(|f| f.name == *formula_name)
.ok_or_else(|| anyhow::anyhow!("Formula '{}' not found", formula_name))?
} else if let Some(formula_text) = &opts.formula_text {
let formula_content = format!("formula TempFormula: {}", formula_text);
let formulas = modality_lang::parse_all_formulas_content_lalrpop(&formula_content)
.map_err(|e| anyhow::anyhow!("Failed to parse formula text: {}", e))?;
formulas.into_iter()
.next()
.ok_or_else(|| anyhow::anyhow!("Failed to parse formula text"))?
} else {
return Err(anyhow::anyhow!("Must specify either --formula or --formula-text"));
};
let checker = modality_lang::ModelChecker::new(model);
let result = checker.check_formula(&formula);
let result_any_state = checker.check_formula_any_state(&formula);
println!("🔍 Checking formula: {}", formula.name);
println!("📋 Formula: {:?}", formula.expression);
println!("");
if result.is_satisfied {
println!("✅ Formula is satisfied (per-graph requirement)");
} else {
println!("❌ Formula is not satisfied (per-graph requirement)");
}
if result_any_state.is_satisfied {
println!("✅ Formula is satisfied (any state)");
} else {
println!("❌ Formula is not satisfied (any state)");
}
println!("");
println!("📍 Satisfying states ({}):", result.satisfying_states.len());
for state in &result.satisfying_states {
println!(" - {}.{}", state.graph_name, state.node_name);
}
Ok(())
}