Skip to content

Commit

Permalink
feat: capable of loading the update function of the whole system c:
Browse files Browse the repository at this point in the history
  • Loading branch information
Lukáš Chudíček committed Oct 7, 2023
1 parent ea12392 commit 1280980
Show file tree
Hide file tree
Showing 5 changed files with 84 additions and 30 deletions.
85 changes: 73 additions & 12 deletions src/prototype/expression.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,10 @@ use crate::{expect_closure_of, expect_opening, expect_opening_of, XmlReader};
pub enum Expression<T> {
Terminal(Proposition<T>),
Not(Box<Expression<T>>),
And(Box<Expression<T>>, Box<Expression<T>>),
Or(Box<Expression<T>>, Box<Expression<T>>),
// And(Box<Expression<T>>, Box<Expression<T>>),
// Or(Box<Expression<T>>, Box<Expression<T>>),
And(Vec<Expression<T>>), // cnf
Or(Vec<Expression<T>>), // dnf
Xor(Box<Expression<T>>, Box<Expression<T>>),
Implies(Box<Expression<T>>, Box<Expression<T>>),
}
Expand Down Expand Up @@ -102,21 +104,80 @@ fn logical_from_xml<T: FromStr, XR: XmlReader<BR>, BR: BufRead>(
expect_closure_of("apply", xml)?; // close *this* apply tag ie the one wrapping the op
Ok(Expression::Not(Box::new(inner)))
}
LogicOp::And | LogicOp::Or | LogicOp::Xor | LogicOp::Implies => {
LogicOp::Xor => {
expect_opening_of("apply", xml)?;
let inner_lhs = Expression::try_from_xml(xml)?;
expect_opening_of("apply", xml)?;
let inner_rhs = Expression::try_from_xml(xml)?;
expect_closure_of("apply", xml)?; // close *this* apply tag ie the one wrapping the op
match op {
LogicOp::And => Ok(Expression::And(Box::new(inner_lhs), Box::new(inner_rhs))),
LogicOp::Or => Ok(Expression::Or(Box::new(inner_lhs), Box::new(inner_rhs))),
LogicOp::Xor => Ok(Expression::Xor(Box::new(inner_lhs), Box::new(inner_rhs))),
LogicOp::Implies => Ok(Expression::Implies(
Box::new(inner_lhs),
Box::new(inner_rhs),
)),
_ => unreachable!(), // because of the not
Ok(Expression::Xor(Box::new(inner_lhs), Box::new(inner_rhs)))
}
LogicOp::Implies => {
expect_opening_of("apply", xml)?;
let inner_lhs = Expression::try_from_xml(xml)?;
expect_opening_of("apply", xml)?;
let inner_rhs = Expression::try_from_xml(xml)?;
expect_closure_of("apply", xml)?; // close *this* apply tag ie the one wrapping the op
Ok(Expression::Implies(
Box::new(inner_lhs),
Box::new(inner_rhs),
))
}
LogicOp::And => {
let cnf_items = get_cnf_or_dnf_items::<T, XR, BR>(xml)?;
Ok(Expression::And(cnf_items))
}
LogicOp::Or => {
let dnf_items = get_cnf_or_dnf_items::<T, XR, BR>(xml)?;
Ok(Expression::Or(dnf_items))
}
}
}

// this could be probably done using process_list, but scuffed so better new fn
/// expects the xml reader to be set so that calling `next()` should encounter
/// either opening of `apply` (encountering the first element), or end of
/// `apply` (signaling the end of the cnf/dnf arguments (so empty cnf/dnf))
fn get_cnf_or_dnf_items<T: FromStr, XR: XmlReader<BR>, BR: BufRead>(
xml: &mut XR,
) -> Result<Vec<Expression<T>>, Box<dyn std::error::Error>> {
let mut acc = Vec::<Expression<T>>::new();

loop {
match xml.next() {
Ok(XmlEvent::Whitespace(_)) => { /* ignore */ }
Ok(XmlEvent::StartElement { name, .. }) => {
if name.local_name == "apply" {
acc.push(Expression::try_from_xml(xml)?);
continue;
}

return Err(format!(
"expected opening of indented apply or closing of this cnf/dnf apply, got opening of {}",
name.local_name
)
.into());
}
Ok(XmlEvent::EndElement { name, .. }) => {
if name.local_name == "apply" {
return Ok(acc);
}

return Err(format!(
"expected opening of indented apply or closing of this cnf/dnf apply, got closing of {}",
name.local_name
)
.into());
}
Ok(XmlEvent::EndDocument) => {
return Err("unexpected end of document".into());
}
other => {
return Err(format!(
"expected either opening of indented apply or closing of this cnf/dnf apply, got {:?}",
other
)
.into());
}
}
}
Expand Down
9 changes: 4 additions & 5 deletions src/prototype/system_update_fn.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ impl SystemUpdateFn {
_xml: &mut XR,
) -> Result<Self, Box<dyn std::error::Error>> {
let var_names_and_upd_fns = load_all_update_fns(_xml)?;
println!("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@");
let ctx = vars_and_their_max_values(&var_names_and_upd_fns);

var_names_and_upd_fns.iter().for_each(|(var_name, upd_fn)| {
Expand Down Expand Up @@ -91,10 +90,10 @@ mod tests {
fn test() {
let file = std::fs::File::open("data/dataset.sbml").expect("cannot open file");
let br = std::io::BufReader::new(file);
let event_reader = xml::reader::EventReader::new(br);
let mut loud = LoudReader::new(event_reader);
let mut reader = xml::reader::EventReader::new(br);
// let mut reader = LoudReader::new(reader); // uncomment to see how xml is loaded

crate::find_start_of(&mut loud, "listOfTransitions").expect("cannot find start of list");
let _system_update_fn = super::SystemUpdateFn::try_from_xml(&mut loud).unwrap();
crate::find_start_of(&mut reader, "listOfTransitions").expect("cannot find start of list");
let _system_update_fn = super::SystemUpdateFn::try_from_xml(&mut reader).unwrap();
}
}
2 changes: 1 addition & 1 deletion src/prototype/update_fn.rs
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ impl<T: FromStr> UpdateFn<T> {
.into());
}

// // listOfInputs might not be present at all
// listOfInputs might not be present at all
let input_vars_names = if some_start_element.name.local_name == "listOfInputs" {
let aux = process_list("listOfInputs", "input", process_input_var_name_item, xml)?;
expect_opening_of("listOfOutputs", xml)?; // must be followed by listOfOutputs
Expand Down
16 changes: 6 additions & 10 deletions src/prototype/update_fn_bdd.rs
Original file line number Diff line number Diff line change
Expand Up @@ -107,16 +107,12 @@ fn bdd_from_expr<D: SymbolicDomain<u8>>(
let bdd = bdd_from_expr(expr, symbolic_domains, bdd_variable_set);
bdd.not()
}
Expression::And(lhs, rhs) => {
let lhs = bdd_from_expr(lhs, symbolic_domains, bdd_variable_set);
let rhs = bdd_from_expr(rhs, symbolic_domains, bdd_variable_set);
lhs.and(&rhs)
}
Expression::Or(lhs, rhs) => {
let lhs = bdd_from_expr(lhs, symbolic_domains, bdd_variable_set);
let rhs = bdd_from_expr(rhs, symbolic_domains, bdd_variable_set);
lhs.or(&rhs)
}
Expression::And(clauses) => clauses.iter().fold(bdd_variable_set.mk_true(), |acc, it| {
acc.and(&bdd_from_expr(it, symbolic_domains, bdd_variable_set))
}),
Expression::Or(clauses) => clauses.iter().fold(bdd_variable_set.mk_false(), |acc, it| {
acc.or(&bdd_from_expr(it, symbolic_domains, bdd_variable_set))
}),
Expression::Xor(lhs, rhs) => {
let lhs = bdd_from_expr(lhs, symbolic_domains, bdd_variable_set);
let rhs = bdd_from_expr(rhs, symbolic_domains, bdd_variable_set);
Expand Down
2 changes: 0 additions & 2 deletions src/prototype/utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -117,8 +117,6 @@ where
loop {
let elem = xml.next();

println!("elem: {:?}", elem);

match elem {
Ok(XmlEvent::Whitespace(_)) => { /* ignore */ }
Ok(XmlEvent::StartElement {
Expand Down

0 comments on commit 1280980

Please sign in to comment.