1use std::sync::Arc;
2use std::fmt;
3use super::Expr;
4
5#[derive(Clone, PartialEq, PartialOrd, Debug)]
7pub enum Symbol {
8 Custom(Arc<String>),
10 Any,
12 Var(Arc<String>),
16 ArityVar(Arc<String>, usize),
18 ListVar(Arc<String>),
20 Singleton(Arc<String>),
24 HeadTailTup(Box<Expr>, Box<Expr>),
29 HeadTailList(Box<Expr>, Box<Expr>),
34 RetVar(Arc<String>),
39 RetIntVar(Arc<String>),
41 RetPosVar(Arc<String>),
43 RetStrictPosVar(Arc<String>),
45 RetNegVar(Arc<String>),
49 NotRetVar(Arc<String>),
51 NotInVarName(Arc<String>, Arc<String>),
54 BinopRetVar(Arc<String>, Arc<String>, Box<Symbol>),
58 TernopRetVar(Arc<String>, Arc<String>, Arc<String>, Box<Symbol>),
62 UnopRetVar(Arc<String>, Box<Symbol>),
66 NoConstrVar(Arc<String>),
68 NoSubstVar(Arc<String>),
70 Dup,
72 False1,
74 Not,
76 Idb,
78 True1,
80 False2,
82 True2,
84 And,
86 Or,
88 Eqb,
90 Xor,
92 Nand,
94 Nor,
96 Exc,
98 Imply,
100 Fstb,
102 Sndb,
104 Even,
106 Odd,
108 Abs,
110 Lt,
112 Rlt,
114 Le,
116 Rle,
118 Gt,
120 Rgt,
122 Ge,
124 Rge,
126 Neg,
128 Inc,
130 Reci,
132 Conj,
134 Norm,
136 Sqnorm,
138 Add,
140 Sub,
142 Rsub,
144 Mul,
146 Mulc,
148 Div,
150 Rdiv,
152 Rem,
154 Pow,
156 Rpow,
158 Sqrt,
160 Ln,
162 Log2,
164 Log10,
166 Exp,
168 Len,
170 Concat,
172 Sum,
174 Min2,
176 Max2,
178 Min,
180 Max,
182 ArgMax,
184 ArgMin,
186 SoftMax,
188 SoftMin,
190 SoftArgMax,
192 SoftArgMin,
194 Range,
196 Rangel,
198 Ranger,
200 Rangem,
202 Prob,
204 Probl,
206 Probr,
208 Probm,
210 MulMat,
212 Col,
216 Det,
218 Dim,
220 Transpose,
222 IsSquareMat,
224 Base,
229 Fst,
231 Snd,
233 Sin,
235 Asin,
237 Cos,
239 Acos,
241 Tan,
243 Atan,
245 Atan2,
247 Dot,
249 Push,
251 PushFront,
253 Item,
255 El,
257 Re,
259 Im,
261 Id,
263 Eq,
265 Neq,
267 Inv,
269 Deriv,
271 Integ,
273 Pariv,
275 If,
279 Ex,
281 Triv,
283 AnyType,
285 RetType,
287 VecType,
289 Rty,
291 VecOp,
295 VecUop,
299 Arity,
301 Pi,
303 Tau,
305 Eps,
307 Imag,
309 Imag2,
311 Imag3,
313 TypeOf,
315 BoolType,
317 F64Type,
319 QuatType,
321 Inf,
323 Both,
325 Neither,
327 Subst,
329}
330
331impl Symbol {
332 pub fn precedence(&self) -> Option<u8> {
334 use Symbol::*;
335
336 Some(match self {
337 Pow | Not => 3,
338 Mul | Div | Rem | And => 4,
339 Add | Sub | Or => 5,
340 Eq => 6,
341 _ => return None,
342 })
343 }
344}
345
346impl From<Arc<String>> for Symbol {
347 fn from(val: Arc<String>) -> Symbol {
348 use Symbol::*;
349
350 match &**val {
351 "_" => Any,
352 "dup" => Dup,
353 "triv" | "∀" | "dom" => Triv,
354 "ex" | "∃" | "codom" => Ex,
355 "false1" => False1,
356 "idb" => Idb,
357 "not" => Not,
358 "true1" => True1,
359 "false2" => False2,
360 "true2" => True2,
361 "and" => And,
362 "or" => Or,
363 "eqb" => Eqb,
364 "xor" => Xor,
365 "nand" => Nand,
366 "nor" => Nor,
367 "exc" => Exc,
368 "imply" => Imply,
369 "fstb" => Fstb,
370 "sndb" => Sndb,
371 "neqb" => Xor,
372 "id" => Id,
373 "inv" => Inv,
374 "lt" => Lt,
375 "rlt" => Rlt,
376 "le" => Le,
377 "rle" => Rle,
378 "gt" => Gt,
379 "rgt" => Rgt,
380 "ge" => Ge,
381 "rge" => Rge,
382 "mul" => Mul,
383 "mulc" => Mulc,
384 "div" => Div,
385 "rem" => Rem,
386 "pow" => Pow,
387 "rpow" => Rpow,
388 "sqrt" => Sqrt,
389 "even" => Even,
390 "odd" => Odd,
391 "abs" => Abs,
392 "neg" => Neg,
393 "inc" => Inc,
394 "reci" => Reci,
395 "conj" => Conj,
396 "norm" => Norm,
397 "sqnorm" => Sqnorm,
398 "add" => Add,
399 "sub" => Sub,
400 "len" => Len,
401 "concat" => Concat,
402 "sum" => Sum,
403 "mul_mat" => MulMat,
404 "col" => Col,
405 "det" => Det,
406 "dim" => Dim,
407 "transpose" => Transpose,
408 "is_square_mat" => IsSquareMat,
409 "base" => Base,
410 "fst" => Fst,
411 "snd" => Snd,
412 "ln" => Ln,
413 "log2" => Log2,
414 "log10" => Log10,
415 "exp" => Exp,
416 "min2" => Min2,
417 "max2" => Max2,
418 "min" => Min,
419 "max" => Max,
420 "arg_max" => ArgMax,
421 "arg_min" => ArgMin,
422 "soft_max" => SoftMax,
423 "soft_min" => SoftMin,
424 "soft_arg_max" => SoftArgMax,
425 "soft_arg_min" => SoftArgMin,
426 "range" => Range,
427 "rangel" => Rangel,
428 "ranger" => Ranger,
429 "rangem" => Rangem,
430 "prob" => Prob,
431 "probl" => Probl,
432 "probr" => Probr,
433 "probm" => Probm,
434 "eq" => Eq,
435 "neq" => Neq,
436 "if" => If,
437 "sin" => Sin,
438 "asin" => Asin,
439 "cos" => Cos,
440 "acos" => Acos,
441 "tan" => Tan,
442 "atan" => Atan,
443 "atan2" => Atan2,
444 "dot" => Dot,
445 "item" => Item,
446 "el" => El,
447 "re" => Re,
448 "im" => Im,
449 "push" => Push,
450 "push_front" => PushFront,
451 "any" => AnyType,
452 "\\" => RetType,
453 "vec" => VecType,
454 "rty" => Rty,
455 "vec_op" => VecOp,
456 "vec_uop" => VecUop,
457 "arity" => Arity,
458 "deriv" | "𝐝" => Deriv,
459 "integ" | "∫" => Integ,
460 "pariv" | "∂" => Pariv,
461 "pi" | "π" => Pi,
462 "tau" | "τ" => Tau,
463 "eps" | "ε" => Eps,
464 "imag" | "𝐢" => Imag,
465 "imag2" | "𝐢₂" => Imag2,
466 "imag3" | "𝐢₃" => Imag3,
467 "type_of" => TypeOf,
468 "bool" => BoolType,
469 "f64" => F64Type,
470 "quat" => QuatType,
471 "inf" | "∞" => Inf,
472 "both" => Both,
473 "neither" => Neither,
474 "subst" => Subst,
475 _ => {
476 let custom_symbol = {
478 let mut chars = val.chars();
479 if let Some(ch) = chars.next() {
480 ch.is_lowercase() && ch.is_alphabetic() &&
481 if let Some(ch) = chars.next() {
482 ch.is_lowercase() && ch.is_alphabetic()
483 } else {false}
484 } else {false}
485 };
486 if custom_symbol {
487 Custom(val)
488 } else {
489 Var(val)
490 }
491 }
492 }
493 }
494}
495
496impl Symbol {
497 pub fn display(
499 &self,
500 w: &mut fmt::Formatter<'_>,
501 rule: bool,
502 ) -> std::result::Result<(), fmt::Error> {
503 use Symbol::*;
504
505 match self {
506 Custom(sym) => write!(w, "{}", sym)?,
507 Dup => write!(w, "dup")?,
508 False1 => write!(w, "false1")?,
509 Not => write!(w, "not")?,
510 Idb => write!(w, "idb")?,
511 True1 => write!(w, "true1")?,
512 False2 => write!(w, "false2")?,
513 True2 => write!(w, "true2")?,
514 And => write!(w, "and")?,
515 Or => write!(w, "or")?,
516 Eqb => write!(w, "eqb")?,
517 Xor => write!(w, "xor")?,
518 Nand => write!(w, "nand")?,
519 Nor => write!(w, "nor")?,
520 Exc => write!(w, "exc")?,
521 Imply => write!(w, "imply")?,
522 Fstb => write!(w, "fstb")?,
523 Sndb => write!(w, "sndb")?,
524 Even => write!(w, "even")?,
525 Odd => write!(w, "odd")?,
526 Abs => write!(w, "abs")?,
527 Lt => write!(w, "lt")?,
528 Rlt => write!(w, "rlt")?,
529 Le => write!(w, "le")?,
530 Rle => write!(w, "rle")?,
531 Gt => write!(w, "gt")?,
532 Rgt => write!(w, "rgt")?,
533 Ge => write!(w, "ge")?,
534 Rge => write!(w, "rge")?,
535 Neg => write!(w, "neg")?,
536 Inc => write!(w, "inc")?,
537 Reci => write!(w, "reci")?,
538 Conj => write!(w, "conj")?,
539 Norm => write!(w, "norm")?,
540 Sqnorm => write!(w, "sqnorm")?,
541 Add => write!(w, "add")?,
542 Sub => write!(w, "sub")?,
543 Rsub => write!(w, "rsub")?,
544 Mul => write!(w, "mul")?,
545 Mulc => write!(w, "mulc")?,
546 Div => write!(w, "div")?,
547 Rdiv => write!(w, "rdiv")?,
548 Rem => write!(w, "rem")?,
549 Pow => write!(w, "pow")?,
550 Rpow => write!(w, "rpow")?,
551 Sqrt => write!(w, "sqrt")?,
552 Ln => write!(w, "ln")?,
553 Log2 => write!(w, "log2")?,
554 Log10 => write!(w, "log10")?,
555 Exp => write!(w, "exp")?,
556 Len => write!(w, "len")?,
557 Concat => write!(w, "concat")?,
558 Sum => write!(w, "sum")?,
559 Min2 => write!(w, "min2")?,
560 Max2 => write!(w, "max2")?,
561 Min => write!(w, "min")?,
562 Max => write!(w, "max")?,
563 ArgMax => write!(w, "arg_max")?,
564 ArgMin => write!(w, "arg_min")?,
565 SoftMax => write!(w, "soft_max")?,
566 SoftMin => write!(w, "soft_min")?,
567 SoftArgMax => write!(w, "soft_arg_max")?,
568 SoftArgMin => write!(w, "soft_arg_min")?,
569 Range => write!(w, "range")?,
570 Rangel => write!(w, "rangel")?,
571 Ranger => write!(w, "ranger")?,
572 Rangem => write!(w, "rangem")?,
573 Prob => write!(w, "prob")?,
574 Probl => write!(w, "probl")?,
575 Probr => write!(w, "probr")?,
576 Probm => write!(w, "probm")?,
577 MulMat => write!(w, "mul_mat")?,
578 Col => write!(w, "col")?,
579 Det => write!(w, "det")?,
580 Dim => write!(w, "dim")?,
581 Transpose => write!(w, "transpose")?,
582 IsSquareMat => write!(w, "is_square_mat")?,
583 Base => write!(w, "base")?,
584 Fst => write!(w, "fst")?,
585 Snd => write!(w, "snd")?,
586 Sin => write!(w, "sin")?,
587 Asin => write!(w, "asin")?,
588 Cos => write!(w, "cos")?,
589 Acos => write!(w, "acos")?,
590 Tan => write!(w, "tan")?,
591 Atan => write!(w, "atan")?,
592 Atan2 => write!(w, "atan2")?,
593 Dot => write!(w, "dot")?,
594 Push => write!(w, "push")?,
595 PushFront => write!(w, "push_front")?,
596 Item => write!(w, "item")?,
597 El => write!(w, "el")?,
598 Re => write!(w, "re")?,
599 Im => write!(w, "im")?,
600 Id => write!(w, "id")?,
601 Eq => write!(w, "eq")?,
602 Neq => write!(w, "neq")?,
603 Inv => write!(w, "inv")?,
604 If => write!(w, "if")?,
605 Any => write!(w, "_")?,
606 Ex => write!(w, "∃")?,
607 Triv => write!(w, "∀")?,
608 AnyType => write!(w, "any")?,
609 RetType => write!(w, "\\")?,
610 VecType => write!(w, "vec")?,
611 Rty => write!(w, "rty")?,
612 VecOp => write!(w, "vec_op")?,
613 VecUop => write!(w, "vec_uop")?,
614 Arity => write!(w, "arity")?,
615 Deriv => write!(w, "𝐝")?,
616 Integ => write!(w, "∫")?,
617 Pariv => write!(w, "∂")?,
618 Pi => write!(w, "π")?,
619 Tau => write!(w, "τ")?,
620 Eps => write!(w, "ε")?,
621 Imag => write!(w, "𝐢")?,
622 Imag2 => write!(w, "𝐢₂")?,
623 Imag3 => write!(w, "𝐢₃")?,
624 TypeOf => write!(w, "type_of")?,
625 BoolType => write!(w, "bool")?,
626 F64Type => write!(w, "f64")?,
627 QuatType => write!(w, "quat")?,
628 Inf => write!(w, "∞")?,
629 Both => write!(w, "both")?,
630 Neither => write!(w, "neither")?,
631 Subst => write!(w, "subst")?,
632 Var(x) => write!(w, "{}", x)?,
633 NoConstrVar(x) => if rule {
634 write!(w, "{}!{{}}", x)?
635 } else {
636 write!(w, "{}", x)?
637 },
638 NoSubstVar(x) => if rule {
639 write!(w, "{}:!subst", x)?
640 } else {
641 write!(w, "{}", x)?
642 },
643 ArityVar(x, arg) => if rule {
644 write!(w, "{}:[arity]{}", x, arg)?
645 } else {
646 write!(w, "{}", x)?
647 },
648 RetVar(x) => write!(w, "\\{}", x)?,
649 RetIntVar(x) => write!(w, "\\{}:int", x)?,
650 RetPosVar(x) => write!(w, "\\{}:(>= 0)", x)?,
651 RetStrictPosVar(x) => write!(w, "\\{}:(> 0)", x)?,
652 RetNegVar(x) => write!(w, "\\{}:(< 0)", x)?,
653 NotRetVar(x) => write!(w, "!\\{}", x)?,
654 NotInVarName(x, y) => write!(w, "{}!>{}", x, y)?,
655 ListVar(x) => write!(w, "[{}..]", x)?,
656 Singleton(x) => write!(w, "\\[{}]", x)?,
657 HeadTailTup(x, y) => write!(w, "({}, {}..)", x, y)?,
658 HeadTailList(x, y) => write!(w, "[{}, {}..]", x, y)?,
659 BinopRetVar(x, y, f) => {
660 match **f {
661 Lt => write!(w, "compute::lt({}, {})", x, y)?,
662 Le => write!(w, "compute::le({}, {})", x, y)?,
663 Gt => write!(w, "compute::gt({}, {})", x, y)?,
664 Ge => write!(w, "compute::ge({}, {})", x, y)?,
665 Add => write!(w, "compute::add({}, {})", x, y)?,
666 Sub => write!(w, "compute::sub({}, {})", x, y)?,
667 Mul => write!(w, "compute::mul({}, {})", x, y)?,
668 Div => write!(w, "compute::div({}, {})", x, y)?,
669 Pow => write!(w, "compute::pow({}, {})", x, y)?,
670 Rem => write!(w, "compute::rem({}, {})", x, y)?,
671 Eq => write!(w, "compute::eq({}, {})", x, y)?,
672 Concat => write!(w, "compute::concat({}, {})", x, y)?,
673 MulMat => write!(w, "compute::mul_mat({}, {})", x, y)?,
674 Push => write!(w, "compute::push({}, {})", x, y)?,
675 PushFront => write!(w, "compute::push_front({}, {})", x, y)?,
676 Max2 => write!(w, "compute::max2({}, {})", x, y)?,
677 Min2 => write!(w, "compute::min2({}, {})", x, y)?,
678 Item => write!(w, "compute::item({}, {})", x, y)?,
679 Col => write!(w, "compute::col({}, {})", x, y)?,
680 Base => write!(w, "compute::base({}, {})", x, y)?,
681 Atan2 => write!(w, "compute::atan2({}, {})", x, y)?,
682 _ => write!(w, "{:?}", self)?,
683 }
684 }
685 TernopRetVar(x, y, z, f) => {
686 match **f {
687 Range => write!(w, "compute::range({}, {}, {})", x, y, z)?,
688 Rangel => write!(w, "compute::rangel({}, {}, {})", x, y, z)?,
689 Ranger => write!(w, "compute::ranger({}, {}, {})", x, y, z)?,
690 Rangem => write!(w, "compute::rangem({}, {}, {})", x, y, z)?,
691 _ => write!(w, "{:?}", self)?,
692 }
693 }
694 UnopRetVar(x, f) => {
695 match **f {
696 Even => write!(w, "compute::even({})", x)?,
697 Odd => write!(w, "compute::odd({})", x)?,
698 Neg => write!(w, "compute::neg({})", x)?,
699 Inc => write!(w, "compute::inc({})", x)?,
700 Reci => write!(w, "compute::reci({})", x)?,
701 Abs => write!(w, "compute::abs({})", x)?,
702 Len => write!(w, "compute::len({})", x)?,
703 Prob => write!(w, "compute::prob({})", x)?,
704 Probl => write!(w, "compute::probl({})", x)?,
705 Probr => write!(w, "compute::probr({})", x)?,
706 Probm => write!(w, "compute::probm({})", x)?,
707 Sqrt => write!(w, "compute::sqrt({})", x)?,
708 Ln => write!(w, "compute::ln({})", x)?,
709 Log2 => write!(w, "compute::log2({})", x)?,
710 Log10 => write!(w, "compute::log10({})", x)?,
711 Exp => write!(w, "compute::exp({})", x)?,
712 Sin => write!(w, "compute::sin({})", x)?,
713 Asin => write!(w, "compute::asin({})", x)?,
714 Cos => write!(w, "compute::cos({})", x)?,
715 Acos => write!(w, "compute::acos({})", x)?,
716 Tan => write!(w, "compute::tan({})", x)?,
717 Atan => write!(w, "compute::atan({})", x)?,
718 Dim => write!(w, "compute::dim({})", x)?,
719 IsSquareMat => write!(w, "compute::is_square_mat({})", x)?,
720 Transpose => write!(w, "compute::transpose({})", x)?,
721 Arity => write!(w, "compute::arity({})", x)?,
722 TypeOf => write!(w, "compute::type_of({})", x)?,
723 _ => write!(w, "{:?}", self)?,
724 }
725 }
726 }
728 Ok(())
729 }
730}
731
732impl fmt::Display for Symbol {
733 fn fmt(&self, w: &mut fmt::Formatter<'_>) -> std::result::Result<(), fmt::Error> {
734 let rule = false;
735 self.display(w, rule)
736 }
737}