1
//! Functions to pretty print a model as a [Minion
2
//! file](https://minion-solver.readthedocs.io/en/latest/usage/input.html).
3

            
4
use std::io::Write;
5

            
6
use crate::ast::{Constant, Constraint, Model, Var, VarName};
7

            
8
/// Writes a complete Minion file for this model to `writer`.
9
2040
pub fn write_minion_file(writer: &mut impl Write, model: &Model) -> Result<(), std::io::Error> {
10
2040
    writeln!(writer, "# Autogenerated by minion-sys")?;
11
2040
    writeln!(writer, "MINION 3")?;
12

            
13
2040
    write_variables_section(writer, model)?;
14
2040
    write_search_section(writer, model)?;
15
2040
    write_constraints_section(writer, model)?;
16
2040
    writeln!(writer, "**EOF**")
17
2040
}
18

            
19
/// Writes the `VARIABLES` section of the Minion file to `writer`.
20
2040
pub fn write_variables_section(
21
2040
    writer: &mut impl Write,
22
2040
    model: &Model,
23
2040
) -> Result<(), std::io::Error> {
24
2040
    writeln!(writer, "**VARIABLES**")?;
25

            
26
2040
    let symtab = &model.named_variables;
27

            
28
    // print variables in declaration order
29
12000
    for name in symtab.get_variable_order() {
30
12000
        write_variable_declaration(writer, model, name)?;
31
    }
32
2040
    Ok(())
33
2040
}
34

            
35
/// Writes the `SEARCH` section of the Minion file to `writer`.
36
2040
pub fn write_search_section(writer: &mut impl Write, model: &Model) -> Result<(), std::io::Error> {
37
    // TODO: print maximising and minimising once we get it
38

            
39
2040
    let symtab = &model.named_variables;
40

            
41
2040
    writeln!(writer, "**SEARCH**")?;
42

            
43
    // no aux vars
44
2040
    let varorder = symtab.get_search_variable_order();
45

            
46
2040
    writeln!(writer, "VARORDER STATIC [{}]", varorder.join(","))
47
2040
}
48

            
49
/// Writes the `CONSTRAINTS` section of the Minion file to `writer`.
50
2040
pub fn write_constraints_section(
51
2040
    writer: &mut impl Write,
52
2040
    model: &Model,
53
2040
) -> Result<(), std::io::Error> {
54
2040
    let constraints = &model.constraints;
55
2040
    writeln!(writer, "**CONSTRAINTS**")?;
56

            
57
5160
    for constraint in constraints {
58
5160
        writeln!(writer, "{constraint}")?;
59
    }
60

            
61
2040
    Ok(())
62
2040
}
63

            
64
/// Writes the variable declaration of `name` to `writer`.
65
///
66
/// # Panics
67
///
68
/// If `name` does not exist.
69
12000
pub fn write_variable_declaration(
70
12000
    writer: &mut impl Write,
71
12000
    model: &Model,
72
12000
    name: VarName,
73
12000
) -> Result<(), std::io::Error> {
74
12000
    let symtab = &model.named_variables;
75

            
76
    #[allow(clippy::expect_used)]
77
12000
    match symtab.get_vartype(name.clone()).expect("name should exist") {
78
        crate::ast::VarDomain::Bound(i, j) => writeln!(writer, "BOUND {name} {{{i}..{j}}}")?,
79
4320
        crate::ast::VarDomain::Discrete(i, j) => writeln!(writer, "DISCRETE {name}, {{{i}..{j}}}")?,
80
7680
        crate::ast::VarDomain::Bool => writeln!(writer, "BOOL {name}")?,
81
    };
82

            
83
12000
    Ok(())
84
12000
}
85

            
86
336
pub(crate) fn print_const_array(array: &[Constant]) -> String {
87
336
    let string_array: Vec<String> = array.iter().map(|x| format!("{x}")).collect();
88
336
    let string = string_array.join(",");
89
336
    format!("[{string}]")
90
336
}
91

            
92
6552
pub(crate) fn print_var_array(array: &[Var]) -> String {
93
12768
    let string_array: Vec<String> = array.iter().map(|x| format!("{x}")).collect();
94
6552
    let string = string_array.join(",");
95
6552
    format!("[{string}]")
96
6552
}
97

            
98
20328
pub(crate) fn print_constraint_array(array: &[Constraint]) -> String {
99
41664
    let string_array: Vec<String> = array.iter().map(|x| format!("{x}")).collect();
100
20328
    let string = string_array.join(",");
101
20328
    format!("[{string}]")
102
20328
}