|
|
@ -6,11 +6,11 @@ use crate::math::Scalar; |
|
|
|
|
|
|
|
|
|
|
|
// an unknown variable with an id
|
|
|
|
// an unknown variable with an id
|
|
|
|
#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord)] |
|
|
|
#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord)] |
|
|
|
struct Unknown(i64); |
|
|
|
pub struct Unknown(i64); |
|
|
|
|
|
|
|
|
|
|
|
type UnknownSet = BTreeSet<Unknown>; |
|
|
|
pub type UnknownSet = BTreeSet<Unknown>; |
|
|
|
|
|
|
|
|
|
|
|
trait Unknowns { |
|
|
|
pub trait Unknowns { |
|
|
|
fn unknowns(&self) -> UnknownSet; |
|
|
|
fn unknowns(&self) -> UnknownSet; |
|
|
|
fn has_unknowns(&self) -> bool; |
|
|
|
fn has_unknowns(&self) -> bool; |
|
|
|
fn has_unknown(&self, u: Unknown) -> bool; |
|
|
|
fn has_unknown(&self, u: Unknown) -> bool; |
|
|
@ -47,7 +47,7 @@ impl fmt::Display for Unknown { |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
#[derive(Clone, Debug, PartialEq)] |
|
|
|
#[derive(Clone, Debug, PartialEq)] |
|
|
|
enum Expr { |
|
|
|
pub enum Expr { |
|
|
|
Unkn(Unknown), |
|
|
|
Unkn(Unknown), |
|
|
|
Const(Scalar), |
|
|
|
Const(Scalar), |
|
|
|
Sum(Exprs), |
|
|
|
Sum(Exprs), |
|
|
@ -56,7 +56,7 @@ enum Expr { |
|
|
|
Div(Box<Expr>, Box<Expr>), |
|
|
|
Div(Box<Expr>, Box<Expr>), |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
type Exprs = Vec<Expr>; |
|
|
|
pub type Exprs = Vec<Expr>; |
|
|
|
|
|
|
|
|
|
|
|
impl Unknowns for Exprs { |
|
|
|
impl Unknowns for Exprs { |
|
|
|
fn unknowns(&self) -> UnknownSet { |
|
|
|
fn unknowns(&self) -> UnknownSet { |
|
|
@ -259,26 +259,26 @@ impl Unknowns for Expr { |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
impl Expr { |
|
|
|
impl Expr { |
|
|
|
fn new_sum(e1: Expr, e2: Expr) -> Expr { |
|
|
|
pub fn new_sum(e1: Expr, e2: Expr) -> Expr { |
|
|
|
Expr::Sum(vec![e1, e2]) |
|
|
|
Expr::Sum(vec![e1, e2]) |
|
|
|
} |
|
|
|
} |
|
|
|
fn new_product(e1: Expr, e2: Expr) -> Expr { |
|
|
|
pub fn new_product(e1: Expr, e2: Expr) -> Expr { |
|
|
|
Expr::Product(vec![e1, e2]) |
|
|
|
Expr::Product(vec![e1, e2]) |
|
|
|
} |
|
|
|
} |
|
|
|
fn new_neg(e1: Expr) -> Expr { |
|
|
|
pub fn new_neg(e1: Expr) -> Expr { |
|
|
|
Expr::Neg(Box::new(e1)) |
|
|
|
Expr::Neg(Box::new(e1)) |
|
|
|
} |
|
|
|
} |
|
|
|
fn new_div(num: Expr, den: Expr) -> Expr { |
|
|
|
pub fn new_div(num: Expr, den: Expr) -> Expr { |
|
|
|
Expr::Div(Box::new(num), Box::new(den)) |
|
|
|
Expr::Div(Box::new(num), Box::new(den)) |
|
|
|
} |
|
|
|
} |
|
|
|
fn new_minus(e1: Expr, e2: Expr) -> Expr { |
|
|
|
pub fn new_minus(e1: Expr, e2: Expr) -> Expr { |
|
|
|
Expr::Sum(vec![e1, Expr::new_neg(e2)]) |
|
|
|
Expr::Sum(vec![e1, Expr::new_neg(e2)]) |
|
|
|
} |
|
|
|
} |
|
|
|
fn new_inv(den: Expr) -> Expr { |
|
|
|
pub fn new_inv(den: Expr) -> Expr { |
|
|
|
Expr::new_div(Expr::Const(1.), den) |
|
|
|
Expr::new_div(Expr::Const(1.), den) |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
fn is_zero(&self) -> bool { |
|
|
|
pub fn is_zero(&self) -> bool { |
|
|
|
use Expr::*; |
|
|
|
use Expr::*; |
|
|
|
match self { |
|
|
|
match self { |
|
|
|
Const(c) => relative_eq!(*c, 0.), |
|
|
|
Const(c) => relative_eq!(*c, 0.), |
|
|
@ -286,7 +286,7 @@ impl Expr { |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
fn is_one(&self) -> bool { |
|
|
|
pub fn is_one(&self) -> bool { |
|
|
|
use Expr::*; |
|
|
|
use Expr::*; |
|
|
|
match self { |
|
|
|
match self { |
|
|
|
Const(c) => relative_eq!(*c, 1.), |
|
|
|
Const(c) => relative_eq!(*c, 1.), |
|
|
@ -294,7 +294,7 @@ impl Expr { |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
fn simplify(self) -> Expr { |
|
|
|
pub fn simplify(self) -> Expr { |
|
|
|
use Expr::*; |
|
|
|
use Expr::*; |
|
|
|
match self { |
|
|
|
match self { |
|
|
|
Sum(es) => { |
|
|
|
Sum(es) => { |
|
|
@ -384,7 +384,7 @@ impl Expr { |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
fn distribute(self) -> Expr { |
|
|
|
pub fn distribute(self) -> Expr { |
|
|
|
use Expr::*; |
|
|
|
use Expr::*; |
|
|
|
trace!("distribute {}", self); |
|
|
|
trace!("distribute {}", self); |
|
|
|
match self { |
|
|
|
match self { |
|
|
@ -444,7 +444,7 @@ impl fmt::Display for Expr { |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
#[derive(Clone, Debug, PartialEq)] |
|
|
|
#[derive(Clone, Debug, PartialEq)] |
|
|
|
struct Eqn(Expr, Expr); |
|
|
|
pub struct Eqn(Expr, Expr); |
|
|
|
|
|
|
|
|
|
|
|
impl Unknowns for Eqn { |
|
|
|
impl Unknowns for Eqn { |
|
|
|
fn unknowns(&self) -> UnknownSet { |
|
|
|
fn unknowns(&self) -> UnknownSet { |
|
|
@ -473,11 +473,15 @@ fn ord_by_unkn(a: Expr, b: Expr, u: Unknown) -> Option<(Expr, Expr)> { |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
impl Eqn { |
|
|
|
impl Eqn { |
|
|
|
fn simplify(self) -> Eqn { |
|
|
|
pub fn new(l: Expr, r: Expr) -> Self { |
|
|
|
|
|
|
|
Self(l, r) |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
pub fn simplify(self) -> Eqn { |
|
|
|
Eqn(self.0.simplify(), self.1.simplify()) |
|
|
|
Eqn(self.0.simplify(), self.1.simplify()) |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
fn solve(&self, for_u: Unknown) -> Option<Expr> { |
|
|
|
pub fn solve(&self, for_u: Unknown) -> Option<Expr> { |
|
|
|
use Expr::*; |
|
|
|
use Expr::*; |
|
|
|
if !self.has_unknown(for_u) { |
|
|
|
if !self.has_unknown(for_u) { |
|
|
|
return None; |
|
|
|
return None; |
|
|
@ -528,7 +532,6 @@ impl Eqn { |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
Const(_) => return None, |
|
|
|
Const(_) => return None, |
|
|
|
_ => return None, |
|
|
|
|
|
|
|
}; |
|
|
|
}; |
|
|
|
l = new_l; |
|
|
|
l = new_l; |
|
|
|
r = new_r; |
|
|
|
r = new_r; |
|
|
@ -543,7 +546,7 @@ impl fmt::Display for Eqn { |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
#[derive(Clone, Debug, PartialEq)] |
|
|
|
#[derive(Clone, Debug, PartialEq)] |
|
|
|
struct Eqns(Vec<Eqn>); |
|
|
|
pub struct Eqns(Vec<Eqn>); |
|
|
|
|
|
|
|
|
|
|
|
impl Unknowns for Eqns { |
|
|
|
impl Unknowns for Eqns { |
|
|
|
fn unknowns(&self) -> UnknownSet { |
|
|
|
fn unknowns(&self) -> UnknownSet { |