Skip to main content

powdr_number/
expression_convertible.rs

1use std::ops::{Add, Mul, Neg, Sub};
2
3use crate::FieldElement;
4
5pub trait ExpressionConvertible<T, V> {
6    /// Converts `self` into a structure that supports algebraic operations.
7    ///
8    /// Fails in case a non-algebraic operation is used.
9    ///
10    /// The `try_to_number` function is used to check if some conversions can be simplified.
11    ///
12    /// This or `to_expression` must be implemented.
13    fn try_to_expression<
14        E: Add<E, Output = E> + Sub<E, Output = E> + Mul<E, Output = E> + Neg<Output = E>,
15    >(
16        &self,
17        number_converter: &impl Fn(&T) -> E,
18        var_converter: &impl Fn(&V) -> E,
19        _try_to_number: &impl Fn(&E) -> Option<T>,
20    ) -> Option<E> {
21        Some(self.to_expression(number_converter, var_converter))
22    }
23
24    /// Converts `self` into a structure that supports algebraic operations.
25    ///
26    /// This or `try_to_expression` must be implemented.
27    fn to_expression<
28        E: Add<E, Output = E> + Sub<E, Output = E> + Mul<E, Output = E> + Neg<Output = E>,
29    >(
30        &self,
31        number_converter: &impl Fn(&T) -> E,
32        var_converter: &impl Fn(&V) -> E,
33    ) -> E {
34        self.try_to_expression(number_converter, var_converter, &|_| unreachable!())
35            .unwrap()
36    }
37}
38
39impl<V, T: FieldElement> ExpressionConvertible<T, V> for T {
40    fn to_expression<
41        E: Add<E, Output = E> + Sub<E, Output = E> + Mul<E, Output = E> + Neg<Output = E>,
42    >(
43        &self,
44        number_converter: &impl Fn(&T) -> E,
45        _var_converter: &impl Fn(&V) -> E,
46    ) -> E {
47        number_converter(self)
48    }
49}