proof_of_sql/sql/proof_exprs/
proof_expr.rs

1use crate::{
2    base::{
3        database::{Column, ColumnRef, ColumnType, LiteralValue, Table},
4        map::{IndexMap, IndexSet},
5        math::decimal::Precision,
6        proof::{PlaceholderResult, ProofError},
7        scalar::Scalar,
8    },
9    sql::proof::{FinalRoundBuilder, VerificationBuilder},
10};
11use bumpalo::Bump;
12use core::fmt::Debug;
13
14/// Provable AST column expression that evaluates to a `Column`
15#[enum_dispatch::enum_dispatch(DynProofExpr)]
16pub trait ProofExpr: Debug + Send + Sync {
17    /// Get the data type of the expression
18    fn data_type(&self) -> ColumnType;
19
20    /// This returns the result of evaluating the expression on the given table, and returns
21    /// a column of values. This result slice is guaranteed to have length `table_length`.
22    /// Implementations must ensure that the returned slice has length `table_length`.
23    fn first_round_evaluate<'a, S: Scalar>(
24        &self,
25        alloc: &'a Bump,
26        table: &Table<'a, S>,
27        params: &[LiteralValue],
28    ) -> PlaceholderResult<Column<'a, S>>;
29
30    /// Evaluate the expression, add components needed to prove it, and return thet resulting column
31    /// of values
32    fn final_round_evaluate<'a, S: Scalar>(
33        &self,
34        builder: &mut FinalRoundBuilder<'a, S>,
35        alloc: &'a Bump,
36        table: &Table<'a, S>,
37        params: &[LiteralValue],
38    ) -> PlaceholderResult<Column<'a, S>>;
39
40    /// Compute the evaluation of a multilinear extension from this expression
41    /// at the random sumcheck point and adds components needed to verify the expression to
42    /// [`VerificationBuilder<S>`]
43    fn verifier_evaluate<S: Scalar>(
44        &self,
45        builder: &mut impl VerificationBuilder<S>,
46        accessor: &IndexMap<ColumnRef, S>,
47        chi_eval: S,
48        params: &[LiteralValue],
49    ) -> Result<S, ProofError>;
50
51    /// Insert in the [`IndexSet`] `columns` all the column
52    /// references in the `BoolExpr` or forwards the call to some
53    /// subsequent `bool_expr`
54    fn get_column_references(&self, columns: &mut IndexSet<ColumnRef>);
55}
56
57/// A trait for `ProofExpr`s that always return a decimal type
58pub(crate) trait DecimalProofExpr: ProofExpr {
59    /// Get the precision of the expression
60    ///
61    /// # Panics
62    /// This panics if the precision is invalid
63    fn precision(&self) -> Precision {
64        Precision::new(
65            self.data_type()
66                .precision_value()
67                .expect("Precision should be valid"),
68        )
69        .expect("Precision should be valid")
70    }
71
72    /// Get the scale of the expression
73    ///
74    /// # Panics
75    /// This panics if the scale is invalid
76    fn scale(&self) -> i8 {
77        self.data_type().scale().expect("Scale should be valid")
78    }
79}