1use std::io::Write;
5
6use crate::ast::{Constant, Constraint, Model, Optimise, ShortTuple, Tuple, Var, VarName};
7
8pub fn write_minion_file(writer: &mut impl Write, model: &Model) -> Result<(), std::io::Error> {
10 writeln!(writer, "# Autogenerated by minion-sys")?;
11 writeln!(writer, "MINION 3")?;
12
13 write_variables_section(writer, model)?;
14 write_search_section(writer, model)?;
15 write_constraints_section(writer, model)?;
16 writeln!(writer, "**EOF**")
17}
18
19pub fn write_variables_section(
21 writer: &mut impl Write,
22 model: &Model,
23) -> Result<(), std::io::Error> {
24 writeln!(writer, "**VARIABLES**")?;
25
26 let symtab = &model.named_variables;
27
28 for name in symtab.get_variable_order() {
30 write_variable_declaration(writer, model, name)?;
31 }
32 Ok(())
33}
34
35pub fn write_search_section(writer: &mut impl Write, model: &Model) -> Result<(), std::io::Error> {
37 let symtab = &model.named_variables;
38
39 writeln!(writer, "**SEARCH**")?;
40
41 let varorder = symtab.get_search_variable_order();
43
44 writeln!(writer, "VARORDER STATIC [{}]", varorder.join(","))?;
45
46 if let Some(Optimise { minimise, var }) = &model.optimise {
47 if *minimise {
48 writeln!(writer, "MINIMISING {var}")?;
49 } else {
50 writeln!(writer, "MAXIMISING {var}")?;
51 }
52 }
53
54 Ok(())
55}
56
57pub fn write_constraints_section(
59 writer: &mut impl Write,
60 model: &Model,
61) -> Result<(), std::io::Error> {
62 let constraints = &model.constraints;
63 writeln!(writer, "**CONSTRAINTS**")?;
64
65 for constraint in constraints {
66 writeln!(writer, "{constraint}")?;
67 }
68
69 Ok(())
70}
71
72pub fn write_variable_declaration(
78 writer: &mut impl Write,
79 model: &Model,
80 name: VarName,
81) -> Result<(), std::io::Error> {
82 let symtab = &model.named_variables;
83
84 #[allow(clippy::expect_used)]
85 match symtab.get_vartype(name.clone()).expect("name should exist") {
86 crate::ast::VarDomain::Bound(i, j) => writeln!(writer, "BOUND {name} {{{i}..{j}}}")?,
87 crate::ast::VarDomain::Discrete(i, j) => writeln!(writer, "DISCRETE {name}, {{{i}..{j}}}")?,
88 crate::ast::VarDomain::Bool => writeln!(writer, "BOOL {name}")?,
89 crate::ast::VarDomain::SparseBound(vals) => {
90 let vals_str: Vec<String> = vals.iter().map(|n| n.to_string()).collect();
91 writeln!(writer, "SPARSEBOUND {name} {{ {} }}", vals_str.join(", "))?
92 }
93 };
94
95 Ok(())
96}
97
98pub(crate) fn print_const_array(array: &[Constant]) -> String {
99 let string_array: Vec<String> = array.iter().map(|x| format!("{x}")).collect();
100 let string = string_array.join(",");
101 format!("[{string}]")
102}
103
104pub(crate) fn print_var_array(array: &[Var]) -> String {
105 let string_array: Vec<String> = array.iter().map(|x| format!("{x}")).collect();
106 let string = string_array.join(",");
107 format!("[{string}]")
108}
109
110pub(crate) fn print_tuple_array(array: &[Tuple]) -> String {
111 let string_array: Vec<String> = array
112 .iter()
113 .map(|tup| format!("[{}]", print_const_array(tup)))
114 .collect();
115 let string = string_array.join(",");
116 format!("[{string}]")
117}
118
119pub(crate) fn print_short_tuple_array(array: &[ShortTuple]) -> String {
120 let string_array: Vec<String> = array
121 .iter()
122 .map(|short| {
123 let pairs: Vec<String> = short
124 .iter()
125 .map(|(idx, val)| format!("({idx},{val})"))
126 .collect();
127 format!("[{}]", pairs.join(","))
128 })
129 .collect();
130 format!("[{}]", string_array.join(","))
131}
132
133pub(crate) fn print_constraint_array(array: &[Constraint]) -> String {
134 let string_array: Vec<String> = array.iter().map(|x| format!("{x}")).collect();
135 let string = string_array.join(",");
136 format!("[{string}]")
137}