smt_lang/solution/
value.rs1use crate::problem::{Expr, GetFromId, InstanceId, Named, ToLang};
2use crate::solve::Smt;
3use fraction::Fraction;
4
5pub enum Value {
6 Instance(InstanceId),
7 Bool(bool),
8 Integer(isize),
9 Real(Fraction),
10}
11
12impl Value {
13 pub fn new(smt: &Smt, model: &z3::Model, expr: &Expr) -> Self {
14 let t = &expr.typ(smt.problem());
15 let expr = &expr.type_inference(smt.problem());
16 if t.is_bool() {
17 let value = model
28 .eval(&smt.to_bool(expr), true)
29 .unwrap()
30 .as_bool()
31 .unwrap();
32 Value::Bool(value)
33 } else if t.is_integer() {
34 let value = model
35 .eval(&smt.to_int(expr), true)
36 .unwrap()
37 .as_i64()
38 .unwrap();
39
40 Value::Integer(value as isize)
41 } else if t.is_real() {
42 let (num, den) = model
43 .eval(&smt.to_real(expr), true)
44 .unwrap()
45 .as_real()
46 .unwrap();
47 let value = if num >= 0 {
48 Fraction::new_generic(fraction::Sign::Plus, num, den).unwrap()
49 } else {
50 Fraction::new_generic(fraction::Sign::Minus, -num, den).unwrap()
51 };
52 Value::Real(value)
53 } else if t.is_structure() {
54 let value = model
55 .eval(&smt.to_datatype(expr), true)
56 .unwrap()
57 .to_string();
58 let instance = smt.problem().find_instance(&value).unwrap();
59 Value::Instance(instance.id())
60 } else if t.is_class() {
61 let value = model
62 .eval(&smt.to_datatype(expr), true)
63 .unwrap()
64 .to_string();
65 let value = value.split(' ').last().unwrap().replace(")", "");
66 let instance = smt.problem().find_instance(&value).unwrap();
67 Value::Instance(instance.id())
68 } else {
69 panic!()
70 }
71 }
72}
73
74impl ToLang for Value {
77 fn to_lang(&self, problem: &crate::problem::Problem) -> String {
78 match self {
79 Value::Instance(id) => problem.get(*id).unwrap().name().to_string(),
80 Value::Bool(value) => value.to_string(),
81 Value::Integer(value) => value.to_string(),
82 Value::Real(value) => value.to_string(),
83 }
84 }
85}