diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/modelica_model.rs | 31 | ||||
-rw-r--r-- | src/transpile_js.rs | 3 | ||||
-rw-r--r-- | src/transpile_scheme.rs | 3 |
3 files changed, 15 insertions, 22 deletions
diff --git a/src/modelica_model.rs b/src/modelica_model.rs index b0bc825..1231546 100644 --- a/src/modelica_model.rs +++ b/src/modelica_model.rs @@ -4,6 +4,7 @@ extern crate modelica_parser; use std::clone::Clone; use std::collections::HashMap; use std::collections::HashSet; +use std::iter::FromIterator; use self::modelica_parser::*; @@ -12,7 +13,7 @@ use self::modelica_parser::*; pub trait ModelicaModelExt { fn get_constant_vars(&self) -> HashMap<String, Option<Expr>>; - fn get_free_vars(&self) -> Vec<String>; + fn get_free_vars(&self) -> HashSet<String>; fn solve_for(&self, indep_vars: Vec<String>, dep_vars: Vec<String>) @@ -41,7 +42,7 @@ impl ModelicaModelExt for ModelicaModel { // the sole element on the LHS of an equation. // Bugs: // if a var is on LHS and RHS of same equation - fn get_free_vars(&self) -> Vec<String> { + fn get_free_vars(&self) -> HashSet<String> { // Start with components, and remove constants and parameters let vars = self.components.iter().filter(|v| match v.prefix { Some(ComponentPrefix::Constant) | @@ -74,6 +75,9 @@ impl ModelicaModelExt for ModelicaModel { indep_vars: Vec<String>, dep_vars: Vec<String>) -> Result<ModelicaModel, String> { + + let indep_vars: HashSet<String> = HashSet::from_iter(indep_vars); + let dep_vars: HashSet<String> = HashSet::from_iter(dep_vars); let constants = self.get_constant_vars(); let mut all_vars: HashSet<String> = HashSet::new(); for eqn in &self.equations { @@ -112,7 +116,7 @@ impl ModelicaModelExt for ModelicaModel { // check that there is a depdendent variable in each equation for eqn in &self.equations { - if intersect_strings(&dep_vars, &eqn.identifiers()).len() == 0 { + if dep_vars.is_disjoint(&eqn.identifiers()) { return Err("NaiveImplementation/OverConstrained: at least one equation is \ missing a dependent variable" .to_string()); @@ -134,19 +138,17 @@ impl ModelicaModelExt for ModelicaModel { let mut solved: Vec<SimpleEquation> = vec![]; let mut unsolved_vars = dep_vars.clone(); while unsolved_eqns.len() > 0 { - println!("vars: {:?} eqns: {:?}", &unsolved_vars, &unsolved_eqns); let next_i = unsolved_eqns.iter() - .position(|ref x| intersect_strings(&unsolved_vars, &x.identifiers()).len() == 1); + .position(|ref x| unsolved_vars.intersection(&x.identifiers()).count() == 1); let eqn = match next_i { None => { return Err("NaiveImplementation (or poor equation selection?)".to_string()); } Some(i) => unsolved_eqns.remove(i), }; - let ref var = intersect_strings(&unsolved_vars, &eqn.identifiers())[0]; - println!("solving: {}; {:?}", var, eqn); + let eqn_tmp = eqn.identifiers(); + let ref var = unsolved_vars.intersection(&eqn_tmp).nth(0).unwrap().clone(); let eqn = eqn.rebalance_for(var.to_string()).expect("rebalance for success"); - println!("got: {:?}", eqn); // Replace all other references to var with RHS of solved equation unsolved_eqns = unsolved_eqns.iter().map(|ref e| SimpleEquation{ @@ -154,8 +156,7 @@ impl ModelicaModelExt for ModelicaModel { rhs: substitute_with(&e.rhs, &Expr::Ident(var.to_string()), &eqn.rhs), }).collect(); solved.push(eqn); - let var_i = unsolved_vars.iter().position(|ref x| x == &var).unwrap(); - unsolved_vars.remove(var_i); + unsolved_vars.remove(var); } Ok(ModelicaModel { @@ -189,16 +190,6 @@ fn substitute_with(original: &Expr, a: &Expr, b: &Expr) -> Expr { } } -fn intersect_strings(a: &Vec<String>, b: &Vec<String>) -> Vec<String> { - let mut both = vec![]; - for e in a { - if b.contains(&e) { - both.push(e.clone()); - } - } - both -} - pub trait SimpleEquationExt { fn rebalance_for(&self, ident: String) -> Result<SimpleEquation, String>; fn simplify_lhs(&self, ident: &str) -> Result<SimpleEquation, String>; diff --git a/src/transpile_js.rs b/src/transpile_js.rs index b14b964..5ca16e6 100644 --- a/src/transpile_js.rs +++ b/src/transpile_js.rs @@ -27,13 +27,14 @@ impl TranspileJS for ModelicaModel { .to_string()); } } + let args: Vec<String> = self.get_free_vars().iter().map(|s| s.clone()).collect(); Ok(format!(r#"function {slug}({args}) {{ {constants} {binds} return [{outputs}]; }}"#, slug = "f", - args = self.get_free_vars().join(", "), + args = args.join(", "), constants = constants.join("\n "), binds = binds.join("\n "), outputs = outputs.join(", "))) diff --git a/src/transpile_scheme.rs b/src/transpile_scheme.rs index 68147e2..8e6d642 100644 --- a/src/transpile_scheme.rs +++ b/src/transpile_scheme.rs @@ -27,11 +27,12 @@ impl TranspileScheme for ModelicaModel { .to_string()); } } + let args: Vec<String> = self.get_free_vars().iter().map(|s| s.clone()).collect(); Ok(format!(r#"(lambda ({args}) (let ({constants}) (letrec ({binds}) (list {outputs}))))"#, - args = self.get_free_vars().join(" "), + args = args.join(" "), constants = constants.join("\n "), binds = binds.join("\n "), outputs = outputs.join(" "))) |