From d75be8f9eaa85bfc437c3d270e2c6497335b4b5c Mon Sep 17 00:00:00 2001 From: Mike Voronov Date: Wed, 24 Nov 2021 18:31:20 +0300 Subject: [PATCH] make apply(_with_tetraplets) always return only one value (#174) --- air/src/execution_step/air/ap/apply_to_arguments.rs | 6 +----- air/src/execution_step/air/fold/utils.rs | 4 ++-- air/src/execution_step/boxed_value/jvaluable.rs | 8 +++----- .../jvaluable/cell_vec_resolved_call_result.rs | 12 +++++------- .../boxed_value/jvaluable/empty_stream.rs | 8 +++----- .../boxed_value/jvaluable/iterable_item.rs | 12 +++++------- .../boxed_value/jvaluable/resolved_call_result.rs | 12 +++++------- .../execution_step/boxed_value/jvaluable/stream.rs | 12 +++++------- air/src/execution_step/utils/resolve.rs | 9 +++++---- 9 files changed, 34 insertions(+), 49 deletions(-) diff --git a/air/src/execution_step/air/ap/apply_to_arguments.rs b/air/src/execution_step/air/ap/apply_to_arguments.rs index ca8f8a26..13c0ed7c 100644 --- a/air/src/execution_step/air/ap/apply_to_arguments.rs +++ b/air/src/execution_step/air/ap/apply_to_arguments.rs @@ -110,11 +110,7 @@ fn apply_scalar_wl_impl( trace_ctx: &TraceHandler, ) -> ExecutionResult { let variable = Variable::scalar(scalar_name, position); - let (jvalue, mut tetraplets) = apply_lambda(variable, lambda, exec_ctx)?; - - let tetraplet = tetraplets - .pop() - .unwrap_or_else(|| Rc::new(RefCell::new(SecurityTetraplet::default()))); + let (jvalue, tetraplet) = apply_lambda(variable, lambda, exec_ctx)?; let result = ValueAggregate::new(Rc::new(jvalue), tetraplet, trace_ctx.trace_pos()); Ok(result) diff --git a/air/src/execution_step/air/fold/utils.rs b/air/src/execution_step/air/fold/utils.rs index 80fd16d4..d6a67709 100644 --- a/air/src/execution_step/air/fold/utils.rs +++ b/air/src/execution_step/air/fold/utils.rs @@ -132,10 +132,10 @@ fn create_scalar_lambda_iterable<'ctx>( } ScalarRef::IterableValue(fold_state) => { let iterable_value = fold_state.iterable.peek().unwrap(); - let jvalues = iterable_value.apply_lambda(lambda)?; + let jvalue = iterable_value.apply_lambda(lambda)?; let tetraplet = as_tetraplet(&iterable_value); - from_jvalue(jvalues[0], tetraplet, lambda) + from_jvalue(jvalue, tetraplet, lambda) } } } diff --git a/air/src/execution_step/boxed_value/jvaluable.rs b/air/src/execution_step/boxed_value/jvaluable.rs index 35758a97..eceb197f 100644 --- a/air/src/execution_step/boxed_value/jvaluable.rs +++ b/air/src/execution_step/boxed_value/jvaluable.rs @@ -25,6 +25,7 @@ use super::ExecutionError; use super::ExecutionResult; use super::ValueAggregate; use crate::execution_step::lambda_applier::*; +use crate::execution_step::RSecurityTetraplet; use crate::execution_step::SecurityTetraplets; use crate::JValue; use crate::LambdaAST; @@ -36,13 +37,10 @@ use std::borrow::Cow; /// Represent a value that could be transform to a JValue with or without tetraplets. pub(crate) trait JValuable { /// Applies lambda to the internal value, produces JValue. - fn apply_lambda(&self, lambda: &LambdaAST<'_>) -> ExecutionResult>; + fn apply_lambda(&self, lambda: &LambdaAST<'_>) -> ExecutionResult<&JValue>; /// Applies lambda to the internal value, produces JValue with tetraplet. - fn apply_lambda_with_tetraplets( - &self, - lambda: &LambdaAST<'_>, - ) -> ExecutionResult<(Vec<&JValue>, SecurityTetraplets)>; + fn apply_lambda_with_tetraplets(&self, lambda: &LambdaAST<'_>) -> ExecutionResult<(&JValue, RSecurityTetraplet)>; /// Return internal value as borrowed if it's possible, owned otherwise. fn as_jvalue(&self) -> Cow<'_, JValue>; diff --git a/air/src/execution_step/boxed_value/jvaluable/cell_vec_resolved_call_result.rs b/air/src/execution_step/boxed_value/jvaluable/cell_vec_resolved_call_result.rs index 08adc9d5..917e8002 100644 --- a/air/src/execution_step/boxed_value/jvaluable/cell_vec_resolved_call_result.rs +++ b/air/src/execution_step/boxed_value/jvaluable/cell_vec_resolved_call_result.rs @@ -18,6 +18,7 @@ use super::select_from_stream; use super::ExecutionResult; use super::JValuable; use super::ValueAggregate; +use crate::execution_step::RSecurityTetraplet; use crate::execution_step::SecurityTetraplets; use crate::JValue; use crate::LambdaAST; @@ -28,23 +29,20 @@ use std::borrow::Cow; use std::ops::Deref; impl JValuable for std::cell::Ref<'_, Vec> { - fn apply_lambda(&self, lambda: &LambdaAST<'_>) -> ExecutionResult> { + fn apply_lambda(&self, lambda: &LambdaAST<'_>) -> ExecutionResult<&JValue> { let stream_iter = self.iter().map(|r| r.result.deref()); let select_result = select_from_stream(stream_iter, lambda)?; - Ok(vec![select_result.result]) + Ok(select_result.result) } - fn apply_lambda_with_tetraplets( - &self, - lambda: &LambdaAST<'_>, - ) -> ExecutionResult<(Vec<&JValue>, SecurityTetraplets)> { + fn apply_lambda_with_tetraplets(&self, lambda: &LambdaAST<'_>) -> ExecutionResult<(&JValue, RSecurityTetraplet)> { let stream_iter = self.iter().map(|r| r.result.deref()); let select_result = select_from_stream(stream_iter, lambda)?; let tetraplet = self[select_result.tetraplet_idx].tetraplet.clone(); tetraplet.borrow_mut().add_lambda(&format_ast(lambda)); - Ok((vec![select_result.result], vec![tetraplet])) + Ok((select_result.result, tetraplet)) } fn as_jvalue(&self) -> Cow<'_, JValue> { diff --git a/air/src/execution_step/boxed_value/jvaluable/empty_stream.rs b/air/src/execution_step/boxed_value/jvaluable/empty_stream.rs index ddb98d63..baacfb3a 100644 --- a/air/src/execution_step/boxed_value/jvaluable/empty_stream.rs +++ b/air/src/execution_step/boxed_value/jvaluable/empty_stream.rs @@ -19,21 +19,19 @@ use super::ExecutionResult; use super::JValuable; use super::LambdaAST; use crate::exec_err; +use crate::execution_step::RSecurityTetraplet; use crate::execution_step::SecurityTetraplets; use crate::JValue; use std::borrow::Cow; impl JValuable for () { - fn apply_lambda(&self, _lambda: &LambdaAST<'_>) -> ExecutionResult> { + fn apply_lambda(&self, _lambda: &LambdaAST<'_>) -> ExecutionResult<&JValue> { // applying lambda to an empty stream will produce a join behaviour exec_err!(ExecutionError::EmptyStreamLambdaError) } - fn apply_lambda_with_tetraplets( - &self, - _lambda: &LambdaAST<'_>, - ) -> ExecutionResult<(Vec<&JValue>, SecurityTetraplets)> { + fn apply_lambda_with_tetraplets(&self, _lambda: &LambdaAST<'_>) -> ExecutionResult<(&JValue, RSecurityTetraplet)> { // applying lambda to an empty stream will produce a join behaviour exec_err!(ExecutionError::EmptyStreamLambdaError) } diff --git a/air/src/execution_step/boxed_value/jvaluable/iterable_item.rs b/air/src/execution_step/boxed_value/jvaluable/iterable_item.rs index 9ce25dc5..a5bf7cb5 100644 --- a/air/src/execution_step/boxed_value/jvaluable/iterable_item.rs +++ b/air/src/execution_step/boxed_value/jvaluable/iterable_item.rs @@ -19,6 +19,7 @@ use super::ExecutionResult; use super::IterableItem; use super::JValuable; use super::LambdaAST; +use crate::execution_step::RSecurityTetraplet; use crate::execution_step::SecurityTetraplets; use crate::JValue; @@ -26,7 +27,7 @@ use std::borrow::Cow; use std::ops::Deref; impl<'ctx> JValuable for IterableItem<'ctx> { - fn apply_lambda(&self, lambda: &LambdaAST<'_>) -> ExecutionResult> { + fn apply_lambda(&self, lambda: &LambdaAST<'_>) -> ExecutionResult<&JValue> { use super::IterableItem::*; let jvalue = match self { @@ -36,13 +37,10 @@ impl<'ctx> JValuable for IterableItem<'ctx> { }; let selected_value = select(jvalue, lambda.iter())?; - Ok(vec![selected_value]) + Ok(selected_value) } - fn apply_lambda_with_tetraplets( - &self, - lambda: &LambdaAST<'_>, - ) -> ExecutionResult<(Vec<&JValue>, SecurityTetraplets)> { + fn apply_lambda_with_tetraplets(&self, lambda: &LambdaAST<'_>) -> ExecutionResult<(&JValue, RSecurityTetraplet)> { use super::IterableItem::*; let (jvalue, tetraplet) = match self { @@ -52,7 +50,7 @@ impl<'ctx> JValuable for IterableItem<'ctx> { }; let selected_value = select(jvalue, lambda.iter())?; - Ok((vec![selected_value], vec![tetraplet.clone()])) + Ok((selected_value, tetraplet.clone())) } fn as_jvalue(&self) -> Cow<'_, JValue> { diff --git a/air/src/execution_step/boxed_value/jvaluable/resolved_call_result.rs b/air/src/execution_step/boxed_value/jvaluable/resolved_call_result.rs index 4f1bc115..a05a1df8 100644 --- a/air/src/execution_step/boxed_value/jvaluable/resolved_call_result.rs +++ b/air/src/execution_step/boxed_value/jvaluable/resolved_call_result.rs @@ -19,6 +19,7 @@ use super::ExecutionResult; use super::JValuable; use super::LambdaAST; use super::ValueAggregate; +use crate::execution_step::RSecurityTetraplet; use crate::execution_step::SecurityTetraplets; use crate::JValue; @@ -28,20 +29,17 @@ use std::borrow::Cow; use std::ops::Deref; impl JValuable for ValueAggregate { - fn apply_lambda(&self, lambda: &LambdaAST<'_>) -> ExecutionResult> { + fn apply_lambda(&self, lambda: &LambdaAST<'_>) -> ExecutionResult<&JValue> { let selected_value = select(&self.result, lambda.iter())?; - Ok(vec![selected_value]) + Ok(selected_value) } - fn apply_lambda_with_tetraplets( - &self, - lambda: &LambdaAST<'_>, - ) -> ExecutionResult<(Vec<&JValue>, SecurityTetraplets)> { + fn apply_lambda_with_tetraplets(&self, lambda: &LambdaAST<'_>) -> ExecutionResult<(&JValue, RSecurityTetraplet)> { let selected_value = select(&self.result, lambda.iter())?; let tetraplet = self.tetraplet.clone(); tetraplet.borrow_mut().add_lambda(&format_ast(lambda)); - Ok((vec![selected_value], vec![tetraplet])) + Ok((selected_value, tetraplet)) } fn as_jvalue(&self) -> Cow<'_, JValue> { diff --git a/air/src/execution_step/boxed_value/jvaluable/stream.rs b/air/src/execution_step/boxed_value/jvaluable/stream.rs index 19608438..f45762b3 100644 --- a/air/src/execution_step/boxed_value/jvaluable/stream.rs +++ b/air/src/execution_step/boxed_value/jvaluable/stream.rs @@ -20,6 +20,7 @@ use super::JValuable; use crate::exec_err; use crate::execution_step::boxed_value::Generation; use crate::execution_step::boxed_value::Stream; +use crate::execution_step::RSecurityTetraplet; use crate::execution_step::SecurityTetraplets; use crate::JValue; use crate::LambdaAST; @@ -38,17 +39,14 @@ pub(crate) struct StreamJvaluableIngredients<'stream> { // TODO: this will be deleted soon, because it would be impossible to use streams without // canonicalization as an arg of a call impl JValuable for StreamJvaluableIngredients<'_> { - fn apply_lambda(&self, lambda: &LambdaAST<'_>) -> ExecutionResult> { + fn apply_lambda(&self, lambda: &LambdaAST<'_>) -> ExecutionResult<&JValue> { let iter = self.iter()?.map(|v| v.result.deref()); let select_result = select_from_stream(iter, lambda)?; - Ok(vec![select_result.result]) + Ok(select_result.result) } - fn apply_lambda_with_tetraplets( - &self, - lambda: &LambdaAST<'_>, - ) -> ExecutionResult<(Vec<&JValue>, SecurityTetraplets)> { + fn apply_lambda_with_tetraplets(&self, lambda: &LambdaAST<'_>) -> ExecutionResult<(&JValue, RSecurityTetraplet)> { let iter = self.iter()?.map(|v| v.result.deref()); let select_result = select_from_stream(iter, lambda)?; @@ -57,7 +55,7 @@ impl JValuable for StreamJvaluableIngredients<'_> { let tetraplet = resolved_call.tetraplet.clone(); tetraplet.borrow_mut().add_lambda(&format_ast(lambda)); - Ok((vec![select_result.result], vec![tetraplet])) + Ok((select_result.result, tetraplet)) } fn as_jvalue(&self) -> Cow<'_, JValue> { diff --git a/air/src/execution_step/utils/resolve.rs b/air/src/execution_step/utils/resolve.rs index 9dc1cf21..0bc92b87 100644 --- a/air/src/execution_step/utils/resolve.rs +++ b/air/src/execution_step/utils/resolve.rs @@ -20,6 +20,7 @@ use crate::execution_step::boxed_value::Variable; use crate::execution_step::execution_context::ExecutionCtx; use crate::execution_step::execution_context::LastErrorWithTetraplet; use crate::execution_step::ExecutionResult; +use crate::execution_step::RSecurityTetraplet; use crate::JValue; use crate::LambdaAST; use crate::SecurityTetraplet; @@ -112,7 +113,7 @@ pub(crate) fn resolve_ast_variable_wl<'ctx, 'i>( ) -> ExecutionResult<(JValue, SecurityTetraplets)> { let variable: Variable<'_> = ast_variable.into(); match ast_variable.lambda() { - Some(lambda) => apply_lambda(variable, lambda, exec_ctx), + Some(lambda) => apply_lambda(variable, lambda, exec_ctx).map(|(value, tetraplet)| (value, vec![tetraplet])), None => { let value = resolve_variable(variable, exec_ctx)?; let tetraplets = value.as_tetraplets(); @@ -125,10 +126,10 @@ pub(crate) fn apply_lambda<'i>( variable: Variable<'_>, lambda: &LambdaAST<'i>, exec_ctx: &ExecutionCtx<'i>, -) -> ExecutionResult<(JValue, SecurityTetraplets)> { +) -> ExecutionResult<(JValue, RSecurityTetraplet)> { let resolved = resolve_variable(variable, exec_ctx)?; - let (jvalue, tetraplets) = resolved.apply_lambda_with_tetraplets(lambda)?; + let (jvalue, tetraplet) = resolved.apply_lambda_with_tetraplets(lambda)?; // it's known that apply_lambda_with_tetraplets returns vec of one value - Ok((jvalue[0].clone(), tetraplets)) + Ok((jvalue.clone(), tetraplet)) }