mod tlc;
mod apalache;
pub use apalache::{cmd_output::ApalacheError, Apalache};
pub use tlc::Tlc;
use std::env;
use std::path::{Path, PathBuf};
use std::str::FromStr;
use serde::Deserialize;
const DEFAULT_TRACES_PER_TEST: usize = 1;
#[derive(Clone, Debug)]
pub struct ModelCheckerRuntime {
pub model_checker: ModelChecker,
pub workers: ModelCheckerWorkers,
pub log: PathBuf,
pub traces_per_test: usize,
}
impl ModelCheckerRuntime {
pub const fn model_checker(mut self, model_checker: ModelChecker) -> Self {
self.model_checker = model_checker;
self
}
pub const fn workers(mut self, workers: ModelCheckerWorkers) -> Self {
self.workers = workers;
self
}
pub fn log(mut self, log: impl AsRef<Path>) -> Self {
self.log = log.as_ref().to_path_buf();
self
}
pub fn traces_per_test(mut self, n: usize) -> Self {
self.traces_per_test = n;
self
}
}
impl Default for ModelCheckerRuntime {
fn default() -> Self {
Self {
model_checker: ModelChecker::Apalache,
workers: ModelCheckerWorkers::Auto,
log: Path::new("mc.log").to_path_buf(),
traces_per_test: DEFAULT_TRACES_PER_TEST,
}
}
}
#[derive(Clone, Copy, Debug, PartialEq, Eq, Deserialize)]
#[serde(rename_all = "snake_case")]
pub enum ModelChecker {
Tlc,
Apalache,
}
impl FromStr for ModelChecker {
type Err = crate::Error;
fn from_str(s: &str) -> Result<Self, Self::Err> {
match s.to_ascii_lowercase().as_str() {
"apalache" => Ok(Self::Apalache),
"tlc" => Ok(Self::Tlc),
other => Err(Self::Err::UnrecognizedChecker(other.into())),
}
}
}
#[derive(Clone, Copy, Debug)]
pub enum ModelCheckerWorkers {
Auto,
Count(usize),
}
impl std::str::FromStr for ModelCheckerWorkers {
type Err = String;
fn from_str(s: &str) -> Result<Self, Self::Err> {
match s {
"auto" => Ok(Self::Auto),
_ => {
if let Ok(count) = s.parse() {
Ok(Self::Count(count))
} else {
Err(unsupported(s))
}
}
}
}
}
fn unsupported(s: &str) -> String {
format!("unsupported value {:?}", s)
}