aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/modelica_model.rs31
-rw-r--r--src/transpile_js.rs3
-rw-r--r--src/transpile_scheme.rs3
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(" ")))