open_hypergraphs/lax/var/
operators.rs1use super::var::*;
2use std::ops::{Add, BitAnd, BitOr, BitXor};
3
4fn binop<O: Clone, A: HasVar>(lhs: Var<O, A>, rhs: Var<O, A>, result_label: O, op: A) -> Var<O, A> {
6 let lhs_node = lhs.new_target();
8 let rhs_node = rhs.new_target();
9
10 let source_type = vec![lhs.label.clone(), rhs.label.clone()];
12 let target_type = vec![result_label.clone()];
13
14 let target = {
15 let mut state = lhs.state.borrow_mut();
16
17 let (_, (s, t)) = state.new_operation(op, source_type, target_type);
19
20 assert_eq!(s.len(), 2);
22 assert_eq!(t.len(), 1);
23
24 state.unify(s[0], lhs_node);
26 state.unify(s[1], rhs_node);
27
28 t[0]
29 };
30
31 let v = Var::new(rhs.state.clone(), result_label);
34 let v_source = v.new_source(); v.state.borrow_mut().unify(target, v_source); v
37}
38
39pub trait HasAdd<O, A> {
41 fn add(lhs_type: O, rhs_type: O) -> (O, A);
42}
43
44impl<O: Clone, A: HasVar + HasAdd<O, A>> Add for Var<O, A> {
45 type Output = Var<O, A>;
46
47 fn add(self, rhs: Self) -> Self::Output {
48 let (result_label, op) = A::add(self.label.clone(), rhs.label.clone());
50 binop(self, rhs, result_label, op)
51 }
52}
53
54pub trait HasBitXor<O, A> {
56 fn bitxor(lhs_type: O, rhs_type: O) -> (O, A);
57}
58
59impl<O: Clone, A: HasVar + HasBitXor<O, A>> BitXor for Var<O, A> {
60 type Output = Var<O, A>;
61
62 fn bitxor(self, rhs: Self) -> Self::Output {
63 let (result_label, op) = A::bitxor(self.label.clone(), rhs.label.clone());
65 binop(self, rhs, result_label, op)
66 }
67}
68
69macro_rules! define_binary_op {
71 ($trait_name:ident, $fn_name:ident, $has_trait_name:ident) => {
72 #[doc = r" Vars support this operator when the underlying signature has the appropriate operation."]
73 pub trait $has_trait_name<O, A> {
74 fn $fn_name(lhs_type: O, rhs_type: O) -> (O, A);
75 }
76
77 impl<O: Clone, A: HasVar + $has_trait_name<O, A>> $trait_name for Var<O, A> {
78 type Output = Var<O, A>;
79
80 fn $fn_name(self, rhs: Self) -> Self::Output {
81 let (result_label, op) = A::$fn_name(self.label.clone(), rhs.label.clone());
82 binop(self, rhs, result_label, op)
83 }
84 }
85 };
86}
87
88define_binary_op!(BitAnd, bitand, HasBitAnd);
89define_binary_op!(BitOr, bitor, HasBitOr);