exxact/expr_rc/mod.rs
1use std::rc::Rc;
2use std::f64::consts::{PI,E};
3
4use crate::{
5 F,
6 One,
7 expr_rc::structs::{Const, Sum, Prod, Sqrt}
8};
9
10
11
12mod from;
13mod ops;
14mod num_traits;
15pub mod structs;
16pub mod simplify;
17pub mod io;
18pub use from::*;
19pub use ops::*;
20pub use num_traits::*;
21
22// #[derive(Debug, PartialEq, Clone)]
23// pub enum VOrRef {
24// Val(F),
25// Ref(Rc<Expr>),
26// }
27
28pub type PVec = Vec<(Expr,F)>;
29pub type SVec = Vec<(F,Expr)>;
30
31// pub struct PVec(PVecT);
32// pub struct SVec(SVecT);
33
34// impl Deref for PVec {type Target = PVecT;fn deref(&self) -> &Self::Target {&self.0}}
35// impl DerefMut for PVec {fn deref_mut(&mut self) -> &mut Self::Target {&mut self.0}}
36// impl PVec {
37// fn new() -> PVec {
38// PVec(PVecT::new())
39// }
40// }
41
42// impl Deref for SVec {type Target = SVecT;fn deref(&self) -> &Self::Target {&self.0}}
43// impl DerefMut for SVec {fn deref_mut(&mut self) -> &mut Self::Target {&mut self.0}}
44// impl SVec {
45// fn new() -> SVec {
46// SVec(SVecT::new())
47// }
48// }
49
50
51// impl fmt::Display for PVec {
52// fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
53// write!(f,"Π[");
54// for (base, exp) in self {
55// write!(f,"({},{}),", base, exp);
56// }
57// write!(f,"]");
58// }
59// }
60
61/// Expression using Rc<T> This type does not know if there are duplicates
62/// use like:
63/// let half = F::new(1u8,2u8); // <- for convenience
64/// let val_1 = Expr::from(1u32);
65/// let val_5 = Expr::from(5u32);
66/// let sqrt_5 = Expr::sqrt(val_5);
67/// let phi = Expr::from(
68/// vec![(half,val_1),(half,sqrt_5)]
69/// )
70/// let phi_sq = Expr::from(
71/// vec![(F::new(3u8,2u8),val_1),(half,sqrt_5)]
72/// )
73/// to be sure that sqrt_5 is shared among phi and phi_sq
74#[derive(PartialEq, Clone)]
75pub enum Expr {
76 /// Just a number
77 /// Needs to be there, since sqrt(2)*sqrt(2) = 2
78 Val(Rc<F>),
79 /// Constant like pi
80 Const(Rc<Const>),
81 /// Sum of terms
82 /// Note that
83 Sum(Rc<Sum>),
84 /// Product of factors
85 /// Notice that e.g. 2pi is already a product
86 Prod(Rc<Prod>),
87 Sqrt(Rc<Sqrt>),
88}
89
90impl Expr {
91 #[inline]
92 pub fn nan() -> Expr {
93 Expr::Val(Rc::new(F::nan()))
94 }
95 #[inline]
96 pub fn infinity() -> Expr {
97 Expr::Val(Rc::new(F::infinity()))
98 }
99 #[inline]
100 pub fn neg_infinity() -> Expr {
101 Expr::Val(Rc::new(F::neg_infinity()))
102 }
103 #[inline]
104 pub fn val_i<T>(i: T) -> Expr where F: From<T>{
105 Expr::Val(Rc::new(F::from(i)))
106 }
107 #[inline]
108 pub fn val_frac(f: F) -> Expr {
109 Expr::Val(Rc::new(f))
110 }
111 #[inline]
112 pub fn c_pi() -> Expr{
113 Expr::Const(Rc::new(Const { ch: 'π', f64: PI }))
114 }
115 #[inline]
116 pub fn c_e() -> Expr{
117 Expr::Const(Rc::new(Const { ch: 'e', f64: E }))
118 }
119 #[inline]
120 pub fn sqrt_i(i: u32) -> Expr {
121 Expr::Sqrt(Rc::new(Sqrt(Expr::val_i(i))))
122 }
123 #[inline]
124 pub fn sqrt_frac(f: F) -> Expr {
125 Expr::Sqrt(Rc::new(Sqrt(Expr::from(f))))
126 }
127 #[inline]
128 pub fn sqrt_expr(expr: Expr) -> Expr {
129 Expr::Sqrt(Rc::new(Sqrt(expr)))
130 }
131 #[inline]
132 pub fn sum_i_pi(i: u32) -> Expr {
133 Expr::Sum(Rc::new(Sum{
134 terms : vec![
135 (F::from(i),Expr::c_pi())
136 ]
137 }))
138 }
139 #[inline]
140 pub fn sum_i_expr(i:u32, e: Expr) -> Expr {
141 Expr::Sum(Rc::new(Sum{
142 terms : vec![
143 (F::from(i),e)
144 ]
145 }))
146 }
147 #[inline]
148 pub fn sum_i_plus_pi(i: u32) -> Expr {
149 Expr::Sum(Rc::new(Sum {
150 terms: vec![
151 (F::from(i),Expr::val_i(1)),
152 (F::one(),Expr::c_pi()),
153 ]
154 }))
155 }
156 /// the golden ratio: (1+sqrt(5))/2 = 1/2+1/2sqrt(5)
157 #[inline]
158 pub fn sum_phi() -> Expr {
159 Expr::Sum(Rc::new(Sum { terms: vec![
160 (F::new(1u8, 2u8), Expr::val_i(1)),
161 (F::new(1u8, 2u8), Expr::sqrt_i(5))
162 ] }))
163 }
164 #[inline]
165 pub fn prod_pi_i(i:u32) -> Expr {
166 Expr::Prod(Rc::new(Prod{factors:vec![
167 (Expr::c_pi(),F::from(i)),
168 ]}))
169 }
170 #[inline]
171 pub fn prod_pi_times_sqrt_i(i: u32) -> Expr {
172 Expr::Prod(Rc::new(Prod { factors: vec![
173 (Expr::c_pi(),F::one()),
174 (Expr::sqrt_i(i),F::one())
175 ] }))
176 }
177}
178
179/// Get the expression of a functional expression, such as Sqrt, Sin, Cos, Tan
180/// Currently only sqrt.
181/// √5/2 -> ξ5/2
182/// Expr::Sqrt(Rc<Sqrt(expr)>) -> expr
183pub trait GetExpr {
184 fn get_expr(&self) -> Option<Expr>;
185}
186
187/// Get the expression of a functional expression, such as Sqrt, Sin, Cos, Tan
188/// Currently only sqrt.
189/// √5/2 -> ξ5/2
190/// Expr::Sqrt(Rc<Sqrt(expr)>) -> expr
191impl GetExpr for Expr {
192 fn get_expr(&self) -> Option<Expr> {
193 match &self {
194 Expr::Sqrt(s) => {
195 Some(s.as_ref().clone().0)
196 },
197 _ => {
198 None
199 }
200 }
201 }
202}
203
204
205
206
207// impl Mul<Expr> for &mut Rc<Expr> {
208// // pub mod sqrt;
209// // pub mod prod;
210// type Output = Rc<Expr>;
211// fn mul(&self, rhs: Expr) -> Self::Output {
212// match Rc::<Expr>::get_mut(self) {
213// Some(s) => {
214// todo!("AA")
215// },
216// None => {
217// match (&*self, rhs) {
218// (Expr::Val(vs), Expr::Val(vr)) => {
219// let m = Rc::<Expr>::get_mut(self);
220// Rc::new(Expr::Val(vs*vr))
221// },
222// _ => {
223// todo!("Implement multiplication for other Rc types")
224// }
225// }
226// }
227// }
228
229// }
230// }
231
232// impl PartialEq for Expr {
233// fn eq(&self, other: &Self) -> bool {
234// false
235// }
236// }
237
238// impl Mul for Expr {
239// type Output = Self;
240// fn mul(&self, rhs: Self) -> Self::Output {
241// match self {
242// Expr::Frac( f ) => {
243// match rhs {
244// Expr::Frac(rhs_f) => {
245// Expr::Frac(f*rhs_f)
246// },
247// Expr::Sum { terms } => {
248// let v = Vec::new();
249// for (coeff, factor) in terms {
250// v.push((f*coeff,factor));
251// }
252// Expr::Sum { terms: v }
253// },
254// // All others: Put it inside a sum with one term
255// rhs => {
256// Expr::Sum { terms: vec![(f, Box::new(rhs))] }
257// }
258// }
259// },
260// Expr::Const { ch, f64 } => {
261// match rhs {
262// Expr::Const { ch, f64 } => {
263// if self == rhs {
264// Expr::Prod { factors: vec![(Box::new(self),F::from(2))] }
265// } else {
266// Expr::Prod { factors: vec![(Box::new(self),F::one()),(Box::new(rhs),F::one())] }
267// }
268// },
269// Expr::Sum { terms } => {
270// let v = Vec::new()
271// for (c,t) in terms {
272// v.push((c, Box::new(*t*self)))
273// }
274// Expr::Sum { terms: v }
275// },
276// Expr::Prod { factors } => {
277// match factors.iter().position(|(e,p)| *e == self) {
278// Some(p) => {
279// let mut f = &factors[p];
280// (*f).1 = (*f).1 + F::one();
281// Expr::Prod { factors: factors }
282// },
283// None => {
284// factors.push((Box::new(self),F::one()));
285// Expr::Prod { factors: factors }
286// }
287// }
288// },
289// _ => {
290// Expr::Prod { factors: vec![
291// (Box::new(rhs),F::one()),
292// (Box::new(self), F::one()),
293// ]}
294// }
295// }
296// },
297// // We are a sum
298// // Only special case is if the other is a sum, then we may be able to simplify
299// // Otherwise, we just distribute the other over ourselves
300// Expr::Sum { terms } => {
301// match rhs {
302// Expr::Frac(f) => {
303// rhs * self
304// },
305// Expr::Const { ch, f64 } => {
306// rhs * self
307// }
308
309// Expr::Sum { terms: rhs_terms } => {
310// for t in terms {
311// for rhs_t in rhs_terms {
312
313// }
314// }
315// }
316// _ => {
317// self
318// }
319// }
320// let v = Vec::new();
321// for (c, e) in terms {
322// v.push((c, Box::new((*e)*self)));
323// }
324// Expr::Sum { terms: v }
325// },
326// Expr::Prod { factors } => {
327
328// },
329// Expr::Sqrt { v } => {
330
331// },
332// Expr::Cos { v } => {
333
334// },
335// Expr::Sin { v } => {
336
337// }
338// }
339// }
340// }
341
342// // Leaf nodes of the structure:
343// // Sqrt(Fraction)
344// // Const
345// //
346// // Sqrt(F) - special multiplication with Sqrt(F)
347// // Also special multiplication for
348// // I think we don't really have to care about leaf nodes.
349// pub struct TSum {
350
351// }
352
353// pub enum FMul {
354// frac(F),
355
356// }
357
358// /// Square root
359// ///
360// #[derive(Debug, PartialEq)]
361// pub struct Sqrt<T> {
362// v: Box<T>
363// }
364
365// /// Composite factor
366// ///
367// pub struct CompF<T> {
368// /// Coefficient
369// c: F,
370// s: Sqrt<T>,
371// /// Factors
372// fs: Vec<Const>,
373// }
374
375
376// #[test]
377// fn sqrt_mul() {
378// let r = Sqrt{v:F::from(5)};
379// let q = Sqrt{v:F::from(2)};
380// assert_eq!(r*r, F::from(5));
381// assert_eq!(r*q, Sqrt{v:F::from(10)})
382// }
383
384// // impl<T> Mul for Sqrt<T> {
385// // fn mul(&self, rhs: Self) {
386
387// // }
388// // }
389
390// /// Something that cannot be further evaluated
391// /// e.g. 'π', √2
392// pub enum Atom {
393// F(F),
394// C(Const),
395// Sqrt(Sqrt<F>),
396// CompF(CompF<F>),
397// // Cos(Cos),
398// // Sin(Sin),
399// }
400
401// /// A multiplication of constants or functions
402// /// Generally cannot be evaluated further
403// /// e.g. π²√2
404// // pub struct Mul {
405// // vals: Vec<(Atom,u32)>
406// // }
407
408// pub struct Fn {
409// ch: char
410// }
411
412// /// A composite value
413// /// e.g. 1/2+1/2√5
414// pub enum Val {
415// C(Const),
416// F(F),
417// // Ex(Expression),
418// }
419
420// // pub struct Term {
421// // c: F,
422
423// // }
424
425// // lazy_static!{
426// // static ref EXACT_CONSTS: HashMap<char, Value<'static>> = {
427// // let mut m = HashMap::new();
428// // let o = Value::Const(CFactor{name: 'o', f64: 0.0});
429// // let x = Value::Const(CFactor{name: 'x', f64: 1.0});
430// // let u = Value::Const(CFactor{name: 'u', f64: 2.0});
431
432// // let q = Value::SimpleSqrt(Sqrt { s_val: Frac::from(2) });
433// // let h = Value::SimpleSqrt(Sqrt { s_val: Frac::from(3) });
434// // let r = Value::SimpleSqrt(Sqrt { s_val: Frac::from(5) });
435// // let vector = vec![o,x,u,q,h,r];
436// // for val in vector {
437// // m.insert(val.name(), val);
438// // }
439// // let f = Value::Ex(Expression{name: 'f', terms: vec!
440// // [
441// // Term{coeff: Frac::new(1u8,2u8), factor: &m[&'x']},
442// // Term{coeff: Frac::new(1u8,2u8), factor: &m[&'r']},
443// // ]}
444// // );
445// // // m.insert(f.name(), f);
446// // m
447// // };
448// // }
449
450// // macro_rules! impl_trait_for_enum {
451// // ($trait_name:ident for $enum_name:ident {
452// // $( $variant:ident($type:ty), )*
453// // } => ($method:ident : $method_type:ty) ) => {
454// // impl $trait_name<$method_type> for $enum_name {
455// // fn $method(&self) -> $method_type {
456// // match self {
457// // $(
458// // $enum_name::$variant(inner) => inner.$method(),
459// // )*
460// // }
461// // }
462// // }
463// // };
464// // }
465
466
467// // / Constant factor
468
469// // #[derive(Debug)]
470// // pub struct CFactor {
471// // name: char,
472// // f64: f64,
473// // }
474
475// // impl PartialEq for CFactor {
476// // fn eq(&self, other: &Self) -> bool {
477// // self.f64 == other.f64
478// // }
479// // }
480
481// // impl TryFrom<&CFactor> for f64 {
482// // // Cannot error
483// // type Error = ();
484// // fn try_from(value: &CFactor) -> Result<Self, Self::Error> {
485// // Ok(value.f64)
486// // }
487// // }
488
489// // impl Name for CFactor {
490// // fn name(&self) -> char{
491// // self.name
492// // }
493// // }
494
495// // /// Square root
496// // /// e.g. √2, √(1+√2)
497// // #[derive(Debug, PartialEq, Eq)]
498// // pub struct Sqrt<T> where T: TryInto<f64>{
499// // s_val: T,
500// // }
501
502// // impl<T: Clone> TryFrom<&Sqrt<T>> for f64 where f64: TryFrom<T>{
503// // type Error = <f64 as TryFrom<T>>::Error;
504// // fn try_from(value: &Sqrt<T>) -> Result<Self, Self::Error> {
505// // match f64::try_from(value.s_val.clone()) {
506// // Ok(s_64) => {
507// // Ok(s_64.sqrt())
508// // }, Err(e) => {
509// // Err(e)
510// // }
511// // }
512// // }
513// // }
514
515// // impl<T> Name for Sqrt<T> where T: TryInto<f64>{
516// // fn name(&self) -> char {
517// // return '√'
518// // }
519// // }
520
521
522// // // impl Name for Value<'_> {
523// // // fn name(&self) -> char {
524// // // match self {
525
526// // // }
527// // // }
528// // // }
529
530// // /// A value that
531// // #[derive(Debug, PartialEq)]
532// // pub enum Value<'a> {
533// // Term(Term<'a>),
534// // Const(CFactor),
535// // Ex(Expression<'a>),
536// // SimpleSqrt(Sqrt<Frac>),
537// // // CompSqrt(Sqrt<&'a Expression<'a>>),
538// // CompF(Vec<&'a Value<'a>>),
539// // }
540
541// // // impl_trait_for_enum!(Name for Value { Const(CFactor), Ex(Sqrt), Term(Term) => name : char });
542// // // impl Name for Value<'_> {
543// // // fn name(&self) -> char {
544// // // match self {
545// // // Value::Const(c) => {
546// // // c.name()
547// // // },
548// // // Value::Ex(e) => {
549// // // e.name()
550// // // },
551// // // Value::Term(t) => {
552// // // t.factor.name()
553// // // }
554// // // Value::CompF(c) => {
555// // // todo!("naming for composite factor")
556// // // },
557// // // Value::SimpleSqrt(s) => {
558// // // todo!("naming for simple square roots")
559// // // }
560// // // }
561// // // }
562// // // }
563
564// // #[derive(Debug, PartialEq)]
565// // pub struct Term<'b> {
566// // coeff: Frac,
567// // factor: &'b Value<'b>
568// // }
569
570// // #[derive(Default, Debug, PartialEq)]
571// // pub struct Expression<'a> {
572// // name: char,
573// // terms: Vec<Term<'a>>
574// // }
575
576// // impl Name for Expression<'_> {
577// // fn name(&self) -> char {
578// // self.name
579// // }
580// // }
581
582// // impl Name for CFactor {
583// // fn name(&self) -> char {
584// // self.val
585// // }
586// // }
587
588// // impl Description for CFactor {
589// // fn description(&self) -> &'static str {
590// // "CFactor"
591// // }
592// // }
593
594// // // #[derive(Debug)]
595// // // struct Sqrt {
596// // // // ... your Sqrt implementation ...
597// // // }
598
599// // impl Name for Sqrt {
600// // fn name(&self) -> char {
601// // // ... your name logic for Sqrt ...
602// // 'S'
603// // }
604// // }
605
606// // impl<T> Description for Sqrt<T> {
607// // fn description(&self) -> &'static str {
608// // "Sqrt"
609// // }
610// // }
611
612// // // #[derive(Debug)]
613// // // struct Term {
614// // // factor: CFactor,
615// // // }
616
617// // impl Name for Term<'_> {
618// // fn name(&self) -> char {
619// // self.factor.name()
620// // }
621// // }
622
623// // impl Description for Term<'_> {
624// // fn description(&self) -> &'static str {
625// // "Term"
626// // }
627// // }
628
629// // // #[derive(Debug)]
630// // // enum Value<'a> {
631// // // Const(CFactor),
632// // // Ex(Sqrt),
633// // // Term(Term),
634// // // }
635
636// // impl_trait_for_enum!(Name for Value, name => char);
637// // // impl_trait_for_enum!(Description for Value, description => &'static str);
638
639// // // fn main() {
640// // // let value = Value::Term(Term { factor: CFactor { val: 'T' } });
641
642// // // println!("Name: {}", value.name());
643// // // println!("Description: {}", value.description());
644// // // }
645
646
647// // #[test]
648// // fn c_factor(){
649// // let pi = Value::Const(CFactor {
650// // name: 'π',
651// // f64: std::f64::consts::PI
652// // });
653// // let one = Value::Const(CFactor {
654// // name: 'x',
655// // f64: 1.0,
656// // });
657// // assert_eq!(pi.name(), 'π');
658// // assert_eq!(f64::try_from(&pi), Ok(std::f64::consts::PI));
659// // assert_eq!(pi + pi, Term{coeff: Frac::from(2), factor: &pi});
660// // assert_eq!(pi + one, Expression{terms: vec![
661// // Term{coeff: Frac::from(1), factor: &one},
662// // Term{coeff: Frac::from(1), factor: &pi},
663// // ]})
664// // // multiplication: not defined!
665// // // assert_eq!(pi * pi, )
666// // // assert_eq!(one * pi, pi);
667// // //
668// // }