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// // }