Skip to content

Commit

Permalink
refactor!: replace output of result_evaluate and `final_round_evalu…
Browse files Browse the repository at this point in the history
…ate` of `ProofPlan` with `Table` (#371)
  • Loading branch information
iajoiner authored Nov 14, 2024
2 parents cecf821 + 6723c5c commit b5a2a7b
Show file tree
Hide file tree
Showing 16 changed files with 202 additions and 133 deletions.
4 changes: 4 additions & 0 deletions crates/proof-of-sql/src/base/database/table.rs
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,10 @@ impl<'a, S: Scalar> Table<'a, S> {
pub fn column_names(&self) -> impl Iterator<Item = &Identifier> {
self.table.keys()
}
/// Returns the columns of this table as an Iterator
pub fn columns(&self) -> impl Iterator<Item = &Column<'a, S>> {
self.table.values()
}
}

// Note: we modify the default PartialEq for IndexMap to also check for column ordering.
Expand Down
18 changes: 16 additions & 2 deletions crates/proof-of-sql/src/base/database/table_utility.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
//! borrowed_decimal75("f", 12, 1, [1, 2, 3], &alloc),
//! ]);
//! ```
use super::{Column, Table};
use super::{Column, Table, TableOptions};
use crate::base::scalar::Scalar;
use alloc::{string::String, vec::Vec};
use bumpalo::Bump;
Expand All @@ -27,7 +27,8 @@ use proof_of_sql_parser::{

/// Creates an [`Table`] from a list of `(Identifier, Column)` pairs.
/// This is a convenience wrapper around [`Table::try_from_iter`] primarily for use in tests and
/// intended to be used along with the other methods in this module (e.g. [bigint], [boolean], etc).
/// intended to be used along with the other methods in this module (e.g. [`borrowed_bigint`],
/// [`borrowed_boolean`], etc).
/// The function will panic under a variety of conditions. See [`Table::try_from_iter`] for more details.
///
/// # Example
Expand All @@ -53,6 +54,19 @@ pub fn table<'a, S: Scalar>(
Table::try_from_iter(iter).unwrap()
}

/// Creates an [`Table`] from a list of `(Identifier, Column)` pairs with a specified row count.
/// The main reason for this function is to allow for creating tables that may potentially have
/// no columns, but still have a specified row count.
///
/// # Panics
/// - Panics if the given row count doesn't match the number of rows in any of the columns.
pub fn table_with_row_count<'a, S: Scalar>(
iter: impl IntoIterator<Item = (Identifier, Column<'a, S>)>,
row_count: usize,
) -> Table<'a, S> {
Table::try_from_iter_with_options(iter, TableOptions::new(Some(row_count))).unwrap()
}

/// Creates a (Identifier, `Column`) pair for a tinyint column.
/// This is primarily intended for use in conjunction with [`table`].
/// # Example
Expand Down
6 changes: 3 additions & 3 deletions crates/proof-of-sql/src/sql/proof/proof_plan.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use super::{CountBuilder, FinalRoundBuilder, FirstRoundBuilder, VerificationBuilder};
use crate::base::{
database::{Column, ColumnField, ColumnRef, DataAccessor, OwnedTable, TableRef},
database::{ColumnField, ColumnRef, DataAccessor, OwnedTable, Table, TableRef},
map::{IndexMap, IndexSet},
proof::ProofError,
scalar::Scalar,
Expand Down Expand Up @@ -40,7 +40,7 @@ pub trait ProverEvaluate {
&self,
alloc: &'a Bump,
accessor: &'a dyn DataAccessor<S>,
) -> Vec<Column<'a, S>>;
) -> Table<'a, S>;

/// Evaluate the query and modify `FirstRoundBuilder` to form the query's proof.
fn first_round_evaluate(&self, builder: &mut FirstRoundBuilder);
Expand All @@ -56,7 +56,7 @@ pub trait ProverEvaluate {
builder: &mut FinalRoundBuilder<'a, S>,
alloc: &'a Bump,
accessor: &'a dyn DataAccessor<S>,
) -> Vec<Column<'a, S>>;
) -> Table<'a, S>;
}

/// Marker used as a trait bound for generic [`ProofPlan`] types to indicate the honesty of their implementation.
Expand Down
14 changes: 13 additions & 1 deletion crates/proof-of-sql/src/sql/proof/provable_query_result.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use super::{decode_and_convert, decode_multiple_elements, ProvableResultColumn, QueryError};
use crate::base::{
database::{Column, ColumnField, ColumnType, OwnedColumn, OwnedTable},
database::{Column, ColumnField, ColumnType, OwnedColumn, OwnedTable, Table},
polynomial::compute_evaluation_vector,
scalar::Scalar,
};
Expand Down Expand Up @@ -219,3 +219,15 @@ impl ProvableQueryResult {
Ok(owned_table)
}
}

impl<S: Scalar> From<Table<'_, S>> for ProvableQueryResult {
fn from(table: Table<S>) -> Self {
let num_rows = table.num_rows();
let columns = table
.into_inner()
.into_iter()
.map(|(_, col)| col)
.collect::<Vec<_>>();
Self::new(num_rows as u64, &columns)
}
}
6 changes: 2 additions & 4 deletions crates/proof-of-sql/src/sql/proof/query_proof.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use crate::{
base::{
bit::BitDistribution,
commitment::CommitmentEvaluationProof,
database::{Column, CommitmentAccessor, DataAccessor, MetadataAccessor, TableRef},
database::{CommitmentAccessor, DataAccessor, MetadataAccessor, TableRef},
map::IndexMap,
math::log2_up,
polynomial::{compute_evaluation_vector, CompositePolynomialInfo},
Expand Down Expand Up @@ -76,9 +76,7 @@ impl<CP: CommitmentEvaluationProof> QueryProof<CP> {
let alloc = Bump::new();

// Evaluate query result
let result_cols = expr.result_evaluate(&alloc, accessor);
let output_length = result_cols.first().map_or(0, Column::len);
let provable_result = ProvableQueryResult::new(output_length as u64, &result_cols);
let provable_result = expr.result_evaluate(&alloc, accessor).into();

// Prover First Round
let mut first_round_builder = FirstRoundBuilder::new();
Expand Down
47 changes: 25 additions & 22 deletions crates/proof-of-sql/src/sql/proof/query_proof_test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,9 @@ use crate::{
commitment::InnerProductProof,
database::{
owned_table_utility::{bigint, owned_table},
Column, ColumnField, ColumnRef, ColumnType, DataAccessor, OwnedTable,
OwnedTableTestAccessor, TableRef,
table_utility::*,
ColumnField, ColumnRef, ColumnType, DataAccessor, OwnedTable, OwnedTableTestAccessor,
Table, TableRef,
},
map::{indexset, IndexMap, IndexSet},
proof::ProofError,
Expand Down Expand Up @@ -44,9 +45,9 @@ impl ProverEvaluate for TrivialTestProofPlan {
&self,
alloc: &'a Bump,
_accessor: &'a dyn DataAccessor<S>,
) -> Vec<Column<'a, S>> {
let col = alloc.alloc_slice_fill_copy(self.length, self.column_fill_value);
vec![Column::BigInt(col)]
) -> Table<'a, S> {
let col = vec![self.column_fill_value; self.length];
table([borrowed_bigint("a1", col, alloc)])
}

fn first_round_evaluate(&self, _builder: &mut FirstRoundBuilder) {}
Expand All @@ -56,14 +57,18 @@ impl ProverEvaluate for TrivialTestProofPlan {
builder: &mut FinalRoundBuilder<'a, S>,
alloc: &'a Bump,
_accessor: &'a dyn DataAccessor<S>,
) -> Vec<Column<'a, S>> {
) -> Table<'a, S> {
let col = alloc.alloc_slice_fill_copy(self.length, self.column_fill_value);
builder.produce_intermediate_mle(col as &[_]);
builder.produce_sumcheck_subpolynomial(
SumcheckSubpolynomialType::Identity,
vec![(S::ONE, vec![Box::new(col as &[_])])],
);
vec![Column::BigInt(col)]
table([borrowed_bigint(
"a1",
vec![self.column_fill_value; self.length],
alloc,
)])
}
}
impl ProofPlan for TrivialTestProofPlan {
Expand Down Expand Up @@ -213,9 +218,8 @@ impl ProverEvaluate for SquareTestProofPlan {
&self,
alloc: &'a Bump,
_accessor: &'a dyn DataAccessor<S>,
) -> Vec<Column<'a, S>> {
let res: &[_] = alloc.alloc_slice_copy(&self.res);
vec![Column::BigInt(res)]
) -> Table<'a, S> {
table([borrowed_bigint("a1", self.res, alloc)])
}

fn first_round_evaluate(&self, _builder: &mut FirstRoundBuilder) {}
Expand All @@ -225,7 +229,7 @@ impl ProverEvaluate for SquareTestProofPlan {
builder: &mut FinalRoundBuilder<'a, S>,
alloc: &'a Bump,
accessor: &'a dyn DataAccessor<S>,
) -> Vec<Column<'a, S>> {
) -> Table<'a, S> {
let x = accessor.get_column(ColumnRef::new(
"sxt.test".parse().unwrap(),
"x".parse().unwrap(),
Expand All @@ -240,7 +244,7 @@ impl ProverEvaluate for SquareTestProofPlan {
(-S::ONE, vec![Box::new(x), Box::new(x)]),
],
);
vec![Column::BigInt(res)]
table([borrowed_bigint("a1", self.res, alloc)])
}
}
impl ProofPlan for SquareTestProofPlan {
Expand Down Expand Up @@ -390,9 +394,8 @@ impl ProverEvaluate for DoubleSquareTestProofPlan {
&self,
alloc: &'a Bump,
_accessor: &'a dyn DataAccessor<S>,
) -> Vec<Column<'a, S>> {
let res: &[_] = alloc.alloc_slice_copy(&self.res);
vec![Column::BigInt(res)]
) -> Table<'a, S> {
table([borrowed_bigint("a1", self.res, alloc)])
}

fn first_round_evaluate(&self, _builder: &mut FirstRoundBuilder) {}
Expand All @@ -402,7 +405,7 @@ impl ProverEvaluate for DoubleSquareTestProofPlan {
builder: &mut FinalRoundBuilder<'a, S>,
alloc: &'a Bump,
accessor: &'a dyn DataAccessor<S>,
) -> Vec<Column<'a, S>> {
) -> Table<'a, S> {
let x = accessor.get_column(ColumnRef::new(
"sxt.test".parse().unwrap(),
"x".parse().unwrap(),
Expand Down Expand Up @@ -430,7 +433,7 @@ impl ProverEvaluate for DoubleSquareTestProofPlan {
],
);
builder.produce_intermediate_mle(res);
vec![Column::BigInt(res)]
table([borrowed_bigint("a1", self.res, alloc)])
}
}
impl ProofPlan for DoubleSquareTestProofPlan {
Expand Down Expand Up @@ -595,10 +598,10 @@ struct ChallengeTestProofPlan {}
impl ProverEvaluate for ChallengeTestProofPlan {
fn result_evaluate<'a, S: Scalar>(
&self,
_alloc: &'a Bump,
alloc: &'a Bump,
_accessor: &'a dyn DataAccessor<S>,
) -> Vec<Column<'a, S>> {
vec![Column::BigInt(&[9, 25])]
) -> Table<'a, S> {
table([borrowed_bigint("a1", [9, 25], alloc)])
}

fn first_round_evaluate(&self, builder: &mut FirstRoundBuilder) {
Expand All @@ -610,7 +613,7 @@ impl ProverEvaluate for ChallengeTestProofPlan {
builder: &mut FinalRoundBuilder<'a, S>,
alloc: &'a Bump,
accessor: &'a dyn DataAccessor<S>,
) -> Vec<Column<'a, S>> {
) -> Table<'a, S> {
let x = accessor.get_column(ColumnRef::new(
"sxt.test".parse().unwrap(),
"x".parse().unwrap(),
Expand All @@ -627,7 +630,7 @@ impl ProverEvaluate for ChallengeTestProofPlan {
(-alpha, vec![Box::new(x), Box::new(x)]),
],
);
vec![Column::BigInt(&[9, 25])]
table([borrowed_bigint("a1", [9, 25], alloc)])
}
}
impl ProofPlan for ChallengeTestProofPlan {
Expand Down
24 changes: 15 additions & 9 deletions crates/proof-of-sql/src/sql/proof/verifiable_query_result_test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,9 @@ use crate::{
commitment::InnerProductProof,
database::{
owned_table_utility::{bigint, owned_table},
Column, ColumnField, ColumnRef, ColumnType, DataAccessor, OwnedTable,
OwnedTableTestAccessor, TableRef,
table_utility::*,
ColumnField, ColumnRef, ColumnType, DataAccessor, OwnedTable, OwnedTableTestAccessor,
Table, TableRef,
},
map::{indexset, IndexMap, IndexSet},
proof::ProofError,
Expand All @@ -29,24 +30,29 @@ impl ProverEvaluate for EmptyTestQueryExpr {
&self,
alloc: &'a Bump,
_accessor: &'a dyn DataAccessor<S>,
) -> Vec<Column<'a, S>> {
let zeros = vec![0; self.length];
let res: &[_] = alloc.alloc_slice_copy(&zeros);
vec![Column::BigInt(res); self.columns]
) -> Table<'a, S> {
let zeros = vec![0_i64; self.length];
table_with_row_count(
(1..=self.columns).map(|i| borrowed_bigint(format!("a{i}"), zeros.clone(), alloc)),
self.length,
)
}
fn first_round_evaluate(&self, _builder: &mut FirstRoundBuilder) {}
fn final_round_evaluate<'a, S: Scalar>(
&self,
builder: &mut FinalRoundBuilder<'a, S>,
alloc: &'a Bump,
_accessor: &'a dyn DataAccessor<S>,
) -> Vec<Column<'a, S>> {
let zeros = vec![0; self.length];
) -> Table<'a, S> {
let zeros = vec![0_i64; self.length];
let res: &[_] = alloc.alloc_slice_copy(&zeros);
let _ = std::iter::repeat_with(|| builder.produce_intermediate_mle(res))
.take(self.columns)
.collect::<Vec<_>>();
vec![Column::BigInt(res); self.columns]
table_with_row_count(
(1..=self.columns).map(|i| borrowed_bigint(format!("a{i}"), zeros.clone(), alloc)),
self.length,
)
}
}
impl ProofPlan for EmptyTestQueryExpr {
Expand Down
2 changes: 1 addition & 1 deletion crates/proof-of-sql/src/sql/proof_plans/dyn_proof_plan.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use super::{EmptyExec, FilterExec, GroupByExec, ProjectionExec, TableExec};
use crate::{
base::{
database::{Column, ColumnField, ColumnRef, DataAccessor, OwnedTable, TableRef},
database::{ColumnField, ColumnRef, DataAccessor, OwnedTable, Table, TableRef},
map::{IndexMap, IndexSet},
proof::ProofError,
scalar::Scalar,
Expand Down
16 changes: 11 additions & 5 deletions crates/proof-of-sql/src/sql/proof_plans/empty_exec.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
use crate::{
base::{
database::{Column, ColumnField, ColumnRef, DataAccessor, OwnedTable, TableRef},
database::{
ColumnField, ColumnRef, DataAccessor, OwnedTable, Table, TableOptions, TableRef,
},
map::{IndexMap, IndexSet},
proof::ProofError,
scalar::Scalar,
Expand Down Expand Up @@ -67,8 +69,10 @@ impl ProverEvaluate for EmptyExec {
&self,
_alloc: &'a Bump,
_accessor: &'a dyn DataAccessor<S>,
) -> Vec<Column<'a, S>> {
Vec::new()
) -> Table<'a, S> {
// Create an empty table with one row
Table::<'a, S>::try_new_with_options(IndexMap::default(), TableOptions::new(Some(1)))
.unwrap()
}

fn first_round_evaluate(&self, _builder: &mut FirstRoundBuilder) {}
Expand All @@ -80,7 +84,9 @@ impl ProverEvaluate for EmptyExec {
_builder: &mut FinalRoundBuilder<'a, S>,
_alloc: &'a Bump,
_accessor: &'a dyn DataAccessor<S>,
) -> Vec<Column<'a, S>> {
Vec::new()
) -> Table<'a, S> {
// Create an empty table with one row
Table::<'a, S>::try_new_with_options(IndexMap::default(), TableOptions::new(Some(1)))
.unwrap()
}
}
Loading

0 comments on commit b5a2a7b

Please sign in to comment.