use btor2rs::id::Nid;
use syn::{parse_quote, Expr, FieldValue};
use crate::translate::btor2::util::create_nid_init_eq_ident;
use super::{
util::{create_nid_ident, create_rnid_expr, single_bits_and},
Error, Translator,
};
impl Translator {
pub(super) fn create_result(&self, is_init: bool) -> Result<Expr, Error> {
let mut field_values = Vec::new();
let mut init_eq_nids = Vec::new();
for (nid, state_info) in &self.state_info_map {
if let Some(next) = state_info.next {
let state_ident = create_nid_ident(*nid);
let returned_ident = if is_init {
let ident = create_nid_ident(*nid);
parse_quote!(#ident)
} else {
create_rnid_expr(next)
};
field_values.push(parse_quote!(#state_ident: #returned_ident));
}
if !is_init && state_info.init.is_some() {
init_eq_nids.push(*nid);
}
}
self.add_drain_field_values(is_init, &mut field_values, &init_eq_nids);
Ok(parse_quote!(State{#(#field_values),*}))
}
fn add_drain_field_values(
&self,
is_init: bool,
field_values: &mut Vec<FieldValue>,
init_eq_nids: &[Nid],
) {
let constraint_exprs = self
.constraints
.iter()
.map(|constraint| -> Expr { create_rnid_expr(*constraint) });
let constraint_expr = single_bits_and(constraint_exprs);
let constraint_expr = if !is_init {
parse_quote!((state.constrained & #constraint_expr))
} else {
constraint_expr
};
field_values.push(parse_quote!(constrained: #constraint_expr));
let not_bad_exprs = self.bads.iter().map(|bad| -> Expr {
let bad_expr: Expr = create_rnid_expr(*bad);
parse_quote!((!#bad_expr))
});
let not_bad_expr = single_bits_and(not_bad_exprs);
let not_constraint_expr: Expr = parse_quote!((!#constraint_expr));
field_values.push(parse_quote!(safe: (#not_constraint_expr | #not_bad_expr)));
if is_init {
field_values.push(parse_quote!(eq_init: ::machine_check::Bitvector::<1>::new(1)));
} else {
let eq_init_exprs = init_eq_nids.iter().map(|init_eq_nid| -> Expr {
let init_ident = create_nid_init_eq_ident(*init_eq_nid);
parse_quote!(#init_ident)
});
let eq_init_expr = single_bits_and(eq_init_exprs);
field_values.push(parse_quote!(eq_init: (#eq_init_expr)));
}
}
}