use serde::{Deserialize, Serialize};
use converge_pack::{ExecutionIdentity, FactPayload};
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
#[serde(deny_unknown_fields)]
pub struct CpVariable {
pub name: String,
pub lb: i64,
pub ub: i64,
#[serde(default)]
pub is_bool: bool,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
#[serde(deny_unknown_fields)]
pub struct IntervalVarDef {
pub name: String,
pub start_var: String,
pub duration: i64,
pub end_var: String,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
#[serde(deny_unknown_fields)]
pub struct OptionalIntervalVarDef {
pub name: String,
pub start_var: String,
pub duration: i64,
pub end_var: String,
pub lit_var: String,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
#[serde(deny_unknown_fields)]
pub struct CpTerm {
pub var: String,
pub coeff: i64,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
#[serde(deny_unknown_fields)]
pub struct CpBoolLiteral {
pub var: String,
#[serde(default)]
pub negated: bool,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
#[serde(deny_unknown_fields)]
pub struct CumulativeDemand {
pub interval: String,
pub demand: i64,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
#[serde(deny_unknown_fields)]
pub struct NoOverlap2DRectangle {
pub x_interval: String,
pub y_interval: String,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
#[serde(tag = "kind", rename_all = "snake_case")]
pub enum ConstraintKind {
LinearLe {
terms: Vec<CpTerm>,
rhs: i64,
},
LinearGe {
terms: Vec<CpTerm>,
rhs: i64,
},
LinearEq {
terms: Vec<CpTerm>,
rhs: i64,
},
AllDifferent {
vars: Vec<String>,
},
BoolOr {
literals: Vec<CpBoolLiteral>,
},
BoolAnd {
literals: Vec<CpBoolLiteral>,
},
BoolXor {
literals: Vec<CpBoolLiteral>,
},
Implication {
antecedent: CpBoolLiteral,
consequent: CpBoolLiteral,
},
AtMostOne {
literals: Vec<CpBoolLiteral>,
},
ExactlyOne {
literals: Vec<CpBoolLiteral>,
},
AllowedAssignments {
vars: Vec<String>,
tuples: Vec<Vec<i64>>,
},
NoOverlap {
intervals: Vec<String>,
},
Cumulative {
demands: Vec<CumulativeDemand>,
capacity: i64,
},
NoOverlap2D {
rectangles: Vec<NoOverlap2DRectangle>,
},
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
#[serde(deny_unknown_fields)]
pub struct CpSatRequest {
pub id: String,
pub variables: Vec<CpVariable>,
#[serde(default)]
pub interval_vars: Vec<IntervalVarDef>,
#[serde(default)]
pub optional_interval_vars: Vec<OptionalIntervalVarDef>,
pub constraints: Vec<ConstraintKind>,
pub objective_terms: Option<Vec<CpTerm>>,
pub minimize: bool,
pub time_limit_seconds: Option<f64>,
}
impl FactPayload for CpSatRequest {
const FAMILY: &'static str = "ferrox.cpsat.request";
const VERSION: u16 = 1;
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
#[serde(deny_unknown_fields)]
pub struct CpSatPlan {
pub request_id: String,
pub status: String,
pub assignments: Vec<(String, i64)>,
pub objective_value: Option<i64>,
pub wall_time_seconds: f64,
pub solver: String,
pub execution_identity: ExecutionIdentity,
}
impl FactPayload for CpSatPlan {
const FAMILY: &'static str = "ferrox.cpsat.plan";
const VERSION: u16 = 1;
}