acme_core/ops/kinds/binary/
mod.rs1pub use self::{args::*, arithmetic::*, specs::*};
6
7pub(crate) mod args;
8pub(crate) mod arithmetic;
9pub(crate) mod specs;
10
11use crate::ops::{Binary, Evaluate, Operand};
12use smart_default::SmartDefault;
13use strum::{Display, EnumCount, EnumIs, EnumIter, EnumString, VariantNames};
14
15impl<O, P, A, B> Evaluate<P> for O
16where
17 O: BinOp<A, B> + Operand<Kind = Binary>,
18 P: BinaryParams<Lhs = A, Rhs = B>,
19{
20 type Output = <O as BinOp<A, B>>::Output;
21
22 fn eval(&self, args: P) -> Self::Output {
23 let (lhs, rhs) = args.into_pattern();
24 BinOp::eval(self, lhs, rhs)
25 }
26}
27
28#[derive(
29 Clone,
30 Copy,
31 Debug,
32 Display,
33 EnumCount,
34 EnumIs,
35 EnumIter,
36 EnumString,
37 Eq,
38 Hash,
39 Ord,
40 PartialEq,
41 PartialOrd,
42 SmartDefault,
43 VariantNames,
44)]
45#[cfg_attr(
46 feature = "serde",
47 derive(serde::Deserialize, serde::Serialize),
48 serde(rename_all = "lowercase", untagged)
49)]
50#[non_exhaustive]
51#[repr(C)]
52#[strum(serialize_all = "lowercase")]
53pub enum BinaryOp {
54 #[default]
56 Arith(Arithmetic),
57 ArithAssign(ArithmeticAssign),
58 Max,
59 Min,
60 And,
61 Or,
62 Xor,
63 Shl,
64 Shr,
65 }
67
68impl BinaryOp {
69 pub fn differentiable(&self) -> bool {
70 match self {
71 Self::Arith(_) | Self::ArithAssign(_) => true,
72 _ => false,
73 }
74 }
75
76 pub fn is_commutative(&self) -> bool {
77 match self {
78 Self::Arith(arith) => arith.is_commutative(),
79 BinaryOp::And | BinaryOp::Or | BinaryOp::Xor => true,
80 _ => false,
81 }
82 }
83 nested_constructor!(
84 Arith<Arithmetic>,
85 arithmetic,
86 [add, div, mul, pow, rem, sub]
87 );
88
89 nested_constructor!(
90 ArithAssign<ArithmeticAssign>,
91 arithmetic_assign,
92 [add_assign, div_assign, mul_assign, rem_assign, sub_assign]
93 );
94
95 variant_constructor!(
99 (Max, max),
100 (Min, min),
101 (And, bitand),
102 (Or, bitor),
103 (Xor, bitxor),
104 (Shl, shl),
105 (Shr, shr)
106 );
107}
108
109impl Operand for BinaryOp {
110 type Kind = Binary;
111
112 fn name(&self) -> &str {
113 match self {
114 Self::Arith(inner) => inner.name(),
115 Self::ArithAssign(inner) => inner.name(),
116 Self::Max => "max",
117 Self::Min => "min",
118 Self::And => "and",
119 Self::Or => "or",
120 Self::Xor => "xor",
121 Self::Shl => "shl",
122 Self::Shr => "shr",
123 }
124 }
125
126 fn optype(&self) -> Self::Kind {
127 Binary
128 }
129}