mod arbitrary;
mod evaluate;
mod parse;
mod serialize;
use derive_more::{Deref, From};
use fnv::FnvHashMap;
use getset::*;
use crate::{Function, SampleID, Sampled, UnknownSampleIDError, VariableIDSet};
pub use arbitrary::*;
#[derive(
Clone,
Copy,
PartialEq,
Eq,
PartialOrd,
Ord,
Hash,
From,
Deref,
serde::Serialize,
serde::Deserialize,
)]
#[serde(transparent)]
pub struct NamedFunctionID(u64);
impl std::fmt::Debug for NamedFunctionID {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "NamedFunctionID({})", self.0)
}
}
impl std::fmt::Display for NamedFunctionID {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
self.0.fmt(f)
}
}
impl NamedFunctionID {
pub fn into_inner(self) -> u64 {
self.0
}
}
#[derive(Debug, Clone, PartialEq)]
pub struct NamedFunction {
pub id: NamedFunctionID,
pub function: Function,
pub name: Option<String>,
pub subscripts: Vec<i64>,
pub parameters: FnvHashMap<String, String>,
pub description: Option<String>,
}
impl std::fmt::Display for NamedFunction {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let name_str = self
.name
.as_ref()
.map(|n| format!("name=\"{n}\""))
.unwrap_or_else(|| "name=None".to_string());
let mut parts = vec![name_str];
if !self.subscripts.is_empty() {
parts.push(format!("subscripts={:?}", self.subscripts));
}
if !self.parameters.is_empty() {
let params: Vec<String> = self
.parameters
.iter()
.map(|(k, v)| format!("{k}={v}"))
.collect();
parts.push(format!("parameters={{{}}}", params.join(", ")));
}
write!(f, "NamedFunction({}, {})", self.function, parts.join(", "))
}
}
#[derive(Debug, Clone, PartialEq, CopyGetters, Getters)]
pub struct EvaluatedNamedFunction {
#[getset(get_copy = "pub")]
pub id: NamedFunctionID,
#[getset(get_copy = "pub")]
pub evaluated_value: f64,
#[getset(get = "pub")]
pub name: Option<String>,
#[getset(get = "pub")]
pub subscripts: Vec<i64>,
#[getset(get = "pub")]
pub parameters: FnvHashMap<String, String>,
#[getset(get = "pub")]
pub description: Option<String>,
#[getset(get = "pub")]
used_decision_variable_ids: VariableIDSet,
}
impl std::fmt::Display for EvaluatedNamedFunction {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let name_str = self
.name
.as_ref()
.map(|n| format!("name=\"{n}\""))
.unwrap_or_else(|| "name=None".to_string());
let mut parts = vec![name_str, format!("value={}", self.evaluated_value)];
if !self.subscripts.is_empty() {
parts.push(format!("subscripts={:?}", self.subscripts));
}
if !self.parameters.is_empty() {
let params: Vec<String> = self
.parameters
.iter()
.map(|(k, v)| format!("{k}={v}"))
.collect();
parts.push(format!("parameters={{{}}}", params.join(", ")));
}
write!(f, "EvaluatedNamedFunction({})", parts.join(", "))
}
}
#[derive(Debug, Clone, PartialEq, Getters)]
pub struct SampledNamedFunction {
#[getset(get = "pub")]
id: NamedFunctionID,
#[getset(get = "pub")]
evaluated_values: Sampled<f64>,
#[getset(get = "pub")]
pub name: Option<String>,
#[getset(get = "pub")]
pub subscripts: Vec<i64>,
#[getset(get = "pub")]
pub parameters: FnvHashMap<String, String>,
#[getset(get = "pub")]
pub description: Option<String>,
#[getset(get = "pub")]
used_decision_variable_ids: VariableIDSet,
}
impl std::fmt::Display for SampledNamedFunction {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let name_str = self
.name
.as_ref()
.map(|n| format!("name=\"{n}\""))
.unwrap_or_else(|| "name=None".to_string());
let mut parts = vec![
name_str,
format!("num_samples={}", self.evaluated_values.num_samples()),
];
if !self.subscripts.is_empty() {
parts.push(format!("subscripts={:?}", self.subscripts));
}
if !self.parameters.is_empty() {
let params: Vec<String> = self
.parameters
.iter()
.map(|(k, v)| format!("{k}={v}"))
.collect();
parts.push(format!("parameters={{{}}}", params.join(", ")));
}
write!(f, "SampledNamedFunction({})", parts.join(", "))
}
}
impl SampledNamedFunction {
pub fn get(&self, sample_id: SampleID) -> Result<EvaluatedNamedFunction, UnknownSampleIDError> {
let evaluated_value = *self.evaluated_values.get(sample_id)?;
Ok(EvaluatedNamedFunction {
id: *self.id(),
evaluated_value,
name: self.name.clone(),
subscripts: self.subscripts.clone(),
parameters: self.parameters.clone(),
description: self.description.clone(),
used_decision_variable_ids: self.used_decision_variable_ids.clone(),
})
}
}