pub fn memoize_expressions(&mut self) {
        // Record the mapping from starting column references to new column
        // references.
        let mut remaps = HashMap::new();
        for index in 0..self.input_arity {
            remaps.insert(index, index);
        }
        let mut new_expressions = Vec::new();

        // We follow the same order as for evaluation, to ensure that all
        // column references exist in time for their evaluation. We could
        // prioritize predicates, but we would need to be careful to chase
        // down column references to expressions and memoize those as well.
        let mut expression = 0;
        for (support, predicate) in self.predicates.iter_mut() {
            while self.input_arity + expression < *support {
                self.expressions[expression].permute_map(&remaps);
                memoize_expr(
                    &mut self.expressions[expression],
                    &mut new_expressions,
                    self.input_arity,
                );
                remaps.insert(
                    self.input_arity + expression,
                    self.input_arity + new_expressions.len(),
                );
                new_expressions.push(self.expressions[expression].clone());
                expression += 1;
            }
            predicate.permute_map(&remaps);
            memoize_expr(predicate, &mut new_expressions, self.input_arity);
        }
        while expression < self.expressions.len() {
            self.expressions[expression].permute_map(&remaps);
            memoize_expr(
                &mut self.expressions[expression],
                &mut new_expressions,
                self.input_arity,
            );
            remaps.insert(
                self.input_arity + expression,
                self.input_arity + new_expressions.len(),
            );
            new_expressions.push(self.expressions[expression].clone());
            expression += 1;
        }

        self.expressions = new_expressions;
        for proj in self.projection.iter_mut() {
            *proj = remaps[proj];
        }
    }
/// Place each certainly evaluated expression in its own column.
///
/// This method places each non-trivial, certainly evaluated expression
/// in its own column, and deduplicates them so that all references to
/// the same expression reference the same column.
///
/// This tranformation is restricted to expressions we are certain will
/// be evaluated, which does not include expressions in `if` statements.
///
/// # Example
///
/// This example demonstrates how memoization notices `MirScalarExpr`s
/// that are used multiple times, and ensures that each are extracted
/// into columns and then referenced by column. This pass does not try
/// to minimize the occurrences of column references, which will happen
/// in inliniing.
///
/// ```rust
/// use expr::{func, MapFilterProject, MirScalarExpr, UnaryFunc, BinaryFunc};
/// // Demonstrate extraction of common expressions (here: parsing strings).
/// let mut map_filter_project = MapFilterProject::new(5)
///     .map(vec![
///         MirScalarExpr::column(0).call_unary(UnaryFunc::CastStringToInt64(func::CastStringToInt64)).call_binary(MirScalarExpr::column(1).call_unary(UnaryFunc::CastStringToInt64(func::CastStringToInt64)), BinaryFunc::AddInt64),
///         MirScalarExpr::column(1).call_unary(UnaryFunc::CastStringToInt64(func::CastStringToInt64)).call_binary(MirScalarExpr::column(2).call_unary(UnaryFunc::CastStringToInt64(func::CastStringToInt64)), BinaryFunc::AddInt64),
///     ])
///     .project(vec![3,4,5,6]);
///
/// let mut expected_optimized = MapFilterProject::new(5)
///     .map(vec![
///         MirScalarExpr::column(0).call_unary(UnaryFunc::CastStringToInt64(func::CastStringToInt64)),
///         MirScalarExpr::column(1).call_unary(UnaryFunc::CastStringToInt64(func::CastStringToInt64)),
///         MirScalarExpr::column(5).call_binary(MirScalarExpr::column(6), BinaryFunc::AddInt64),
///         MirScalarExpr::column(7),
///         MirScalarExpr::column(2).call_unary(UnaryFunc::CastStringToInt64(func::CastStringToInt64)),
///         MirScalarExpr::column(6).call_binary(MirScalarExpr::column(9), BinaryFunc::AddInt64),
///         MirScalarExpr::column(10),
///     ])
///     .project(vec![3,4,8,11]);
///
/// // Memoize expressions, ensuring uniqueness of each `MirScalarExpr`.
/// map_filter_project.memoize_expressions();
///
/// assert_eq!(
///     map_filter_project,
///     expected_optimized,
/// );
/// ```
///
/// Expressions may not be memoized if they are not certain to be evaluated,
/// for example if they occur in conditional branches of a `MirScalarExpr::If`.
///
/// ```rust
/// use expr::{MapFilterProject, MirScalarExpr, UnaryFunc, BinaryFunc};
/// // Demonstrate extraction of unconditionally evaluated expressions, as well as
/// // the non-extraction of common expressions guarded by conditions.
/// let mut map_filter_project = MapFilterProject::new(2)
///     .map(vec![
///         MirScalarExpr::If {
///             cond: Box::new(MirScalarExpr::column(0).call_binary(MirScalarExpr::column(1), BinaryFunc::Lt)),
///             then: Box::new(MirScalarExpr::column(0).call_binary(MirScalarExpr::column(1), BinaryFunc::DivInt64)),
///             els:  Box::new(MirScalarExpr::column(1).call_binary(MirScalarExpr::column(0), BinaryFunc::DivInt64)),
///         },
///         MirScalarExpr::If {
///             cond: Box::new(MirScalarExpr::column(0).call_binary(MirScalarExpr::column(1), BinaryFunc::Lt)),
///             then: Box::new(MirScalarExpr::column(1).call_binary(MirScalarExpr::column(0), BinaryFunc::DivInt64)),
///             els:  Box::new(MirScalarExpr::column(0).call_binary(MirScalarExpr::column(1), BinaryFunc::DivInt64)),
///         },
///     ]);
///
/// let mut expected_optimized = MapFilterProject::new(2)
///     .map(vec![
///         MirScalarExpr::column(0).call_binary(MirScalarExpr::column(1), BinaryFunc::Lt),
///         MirScalarExpr::If {
///             cond: Box::new(MirScalarExpr::column(2)),
///             then: Box::new(MirScalarExpr::column(0).call_binary(MirScalarExpr::column(1), BinaryFunc::DivInt64)),
///             els:  Box::new(MirScalarExpr::column(1).call_binary(MirScalarExpr::column(0), BinaryFunc::DivInt64)),
///         },
///         MirScalarExpr::column(3),
///         MirScalarExpr::If {
///             cond: Box::new(MirScalarExpr::column(2)),
///             then: Box::new(MirScalarExpr::column(1).call_binary(MirScalarExpr::column(0), BinaryFunc::DivInt64)),
///             els:  Box::new(MirScalarExpr::column(0).call_binary(MirScalarExpr::column(1), BinaryFunc::DivInt64)),
///         },
///         MirScalarExpr::column(5),
///     ])
///     .project(vec![0,1,4,6]);
///
/// // Memoize expressions, ensuring uniqueness of each `MirScalarExpr`.
/// map_filter_project.memoize_expressions();
///
/// assert_eq!(
///     map_filter_project,
///     expected_optimized,
/// );
/// ```
Place each certainly evaluated expression in its own column.
This method places each non-trivial, certainly evaluated expression
in its own column, and deduplicates them so that all references to
the same expression reference the same column.

This tranformation is restricted to expressions we are certain will
be evaluated, which does not include expressions in `if` statements.
Place each certainly evaluated expression in its own column . This method places each non - trivial certainly evaluated expression in its own column and deduplicates them so that all references to the same expression reference the same column . This tranformation is restricted to expressions we are certain will be evaluated which does not include expressions in ` if ` statements .
pub fn memoize_expressions(&mut self) {
        // Record the mapping from starting column references to new column
        // references.
        let mut remaps = HashMap::new();
        for index in 0..self.input_arity {
            remaps.insert(index, index);
        }
        let mut new_expressions = Vec::new();
        // We follow the same order as for evaluation, to ensure that all
        // column references exist in time for their evaluation. We could
        // prioritize predicates, but we would need to be careful to chase
        // down column references to expressions and memoize those as well.
        let mut expression = 0;
        for (support, predicate) in self.predicates.iter_mut() {
            while self.input_arity + expression < *support {
                self.expressions[expression].permute_map(&remaps);
                memoize_expr(
                    &mut self.expressions[expression],
                    &mut new_expressions,
                    self.input_arity,
                );
                remaps.insert(
                    self.input_arity + expression,
                    self.input_arity + new_expressions.len(),
                );
                new_expressions.push(self.expressions[expression].clone());
                expression += 1;
            }
            predicate.permute_map(&remaps);
            memoize_expr(predicate, &mut new_expressions, self.input_arity);
        }
        while expression < self.expressions.len() {
            self.expressions[expression].permute_map(&remaps);
            memoize_expr(
                &mut self.expressions[expression],
                &mut new_expressions,
                self.input_arity,
            );
            remaps.insert(
                self.input_arity + expression,
                self.input_arity + new_expressions.len(),
            );
            new_expressions.push(self.expressions[expression].clone());
            expression += 1;
        }
        self.expressions = new_expressions;
        for proj in self.projection.iter_mut() {
            *proj = remaps[proj];
        }
    }
pub fn memoize_expressions ( & mut self ) { // Record the mapping from starting column references to new column // references. let mut remaps = HashMap :: new ( ) ; for index in 0 .. self . input_arity { remaps . insert ( index , index ) ; } let mut new_expressions = Vec :: new ( ) ; // We follow the same order as for evaluation, to ensure that all // column references exist in time for their evaluation. We could // prioritize predicates, but we would need to be careful to chase // down column references to expressions and memoize those as well. let mut expression = 0 ; for ( support , predicate ) in self . predicates . iter_mut ( ) { while self . input_arity + expression < * support { self . expressions [ expression ] . permute_map ( & remaps ) ; memoize_expr ( & mut self . expressions [ expression ] , & mut new_expressions , self . input_arity , ) ; remaps . insert ( self . input_arity + expression , self . input_arity + new_expressions . len ( ) , ) ; new_expressions . push ( self . expressions [ expression ] . clone ( ) ) ; expression += 1 ; } predicate . permute_map ( & remaps ) ; memoize_expr ( predicate , & mut new_expressions , self . input_arity ) ; } while expression < self . expressions . len ( ) { self . expressions [ expression ] . permute_map ( & remaps ) ; memoize_expr ( & mut self . expressions [ expression ] , & mut new_expressions , self . input_arity , ) ; remaps . insert ( self . input_arity + expression , self . input_arity + new_expressions . len ( ) , ) ; new_expressions . push ( self . expressions [ expression ] . clone ( ) ) ; expression += 1 ; } self . expressions = new_expressions ; for proj in self . projection . iter_mut ( ) { * proj = remaps [ proj ] ; } }
Place each certainly evaluated expression in its own column.
Place each certainly evaluated expression in its own column .
&mut self
&mut self
example
This example demonstrates how memoization notices `MirScalarExpr`s
that are used multiple times, and ensures that each are extracted
into columns and then referenced by column. This pass does not try
to minimize the occurrences of column references, which will happen
in inliniing.

```rust
use expr::{func, MapFilterProject, MirScalarExpr, UnaryFunc, BinaryFunc};
Demonstrate extraction of common expressions (here: parsing strings).
let mut map_filter_project = MapFilterProject::new(5)
.map(vec![
MirScalarExpr::column(0).call_unary(UnaryFunc::CastStringToInt64(func::CastStringToInt64)).call_binary(MirScalarExpr::column(1).call_unary(UnaryFunc::CastStringToInt64(func::CastStringToInt64)), BinaryFunc::AddInt64),
MirScalarExpr::column(1).call_unary(UnaryFunc::CastStringToInt64(func::CastStringToInt64)).call_binary(MirScalarExpr::column(2).call_unary(UnaryFunc::CastStringToInt64(func::CastStringToInt64)), BinaryFunc::AddInt64),
])
.project(vec![3,4,5,6]).

let mut expected_optimized = MapFilterProject::new(5)
.map(vec![
MirScalarExpr::column(0).call_unary(UnaryFunc::CastStringToInt64(func::CastStringToInt64)),
MirScalarExpr::column(1).call_unary(UnaryFunc::CastStringToInt64(func::CastStringToInt64)),
MirScalarExpr::column(5).call_binary(MirScalarExpr::column(6), BinaryFunc::AddInt64),
MirScalarExpr::column(7),
MirScalarExpr::column(2).call_unary(UnaryFunc::CastStringToInt64(func::CastStringToInt64)),
MirScalarExpr::column(6).call_binary(MirScalarExpr::column(9), BinaryFunc::AddInt64),
MirScalarExpr::column(10),
])
.project(vec![3,4,8,11]).

Memoize expressions, ensuring uniqueness of each `MirScalarExpr`.



Expressions may not be memoized if they are not certain to be evaluated,
for example if they occur in conditional branches of a `MirScalarExpr::If`.

```rust
use expr::{MapFilterProject, MirScalarExpr, UnaryFunc, BinaryFunc};
Demonstrate extraction of unconditionally evaluated expressions, as well as
the non-extraction of common expressions guarded by conditions.
let mut map_filter_project = MapFilterProject::new(2)
.map(vec![
MirScalarExpr::If {
cond: Box::new(MirScalarExpr::column(0).call_binary(MirScalarExpr::column(1), BinaryFunc::Lt)),
then: Box::new(MirScalarExpr::column(0).call_binary(MirScalarExpr::column(1), BinaryFunc::DivInt64)),
els:  Box::new(MirScalarExpr::column(1).call_binary(MirScalarExpr::column(0), BinaryFunc::DivInt64)),
},
MirScalarExpr::If {
cond: Box::new(MirScalarExpr::column(0).call_binary(MirScalarExpr::column(1), BinaryFunc::Lt)),
then: Box::new(MirScalarExpr::column(1).call_binary(MirScalarExpr::column(0), BinaryFunc::DivInt64)),
els:  Box::new(MirScalarExpr::column(0).call_binary(MirScalarExpr::column(1), BinaryFunc::DivInt64)),
},
]).

let mut expected_optimized = MapFilterProject::new(2)
.map(vec![
MirScalarExpr::column(0).call_binary(MirScalarExpr::column(1), BinaryFunc::Lt),
MirScalarExpr::If {
cond: Box::new(MirScalarExpr::column(2)),
then: Box::new(MirScalarExpr::column(0).call_binary(MirScalarExpr::column(1), BinaryFunc::DivInt64)),
els:  Box::new(MirScalarExpr::column(1).call_binary(MirScalarExpr::column(0), BinaryFunc::DivInt64)),
},
MirScalarExpr::column(3),
MirScalarExpr::If {
cond: Box::new(MirScalarExpr::column(2)),
then: Box::new(MirScalarExpr::column(1).call_binary(MirScalarExpr::column(0), BinaryFunc::DivInt64)),
els:  Box::new(MirScalarExpr::column(0).call_binary(MirScalarExpr::column(1), BinaryFunc::DivInt64)),
},
MirScalarExpr::column(5),
])
.project(vec![0,1,4,6]).

Memoize expressions, ensuring uniqueness of each `MirScalarExpr`.


This example demonstrates how memoization notices ` MirScalarExpr ` s that are used multiple times and ensures that each are extracted into columns and then referenced by column . This pass does not try to minimize the occurrences of column references which will happen in inliniing . ` ` ` rust use expr :: { func MapFilterProject MirScalarExpr UnaryFunc BinaryFunc } ; Demonstrate extraction of common expressions ( here : parsing strings ) . let mut map_filter_project = MapFilterProject :: new ( 5 ) . map ( vec! [ MirScalarExpr :: column ( 0 ) . call_unary ( UnaryFunc :: CastStringToInt64 ( func :: CastStringToInt64 )) . call_binary ( MirScalarExpr :: column ( 1 ) . call_unary ( UnaryFunc :: CastStringToInt64 ( func :: CastStringToInt64 )) BinaryFunc :: AddInt64 ) MirScalarExpr :: column ( 1 ) . call_unary ( UnaryFunc :: CastStringToInt64 ( func :: CastStringToInt64 )) . call_binary ( MirScalarExpr :: column ( 2 ) . call_unary ( UnaryFunc :: CastStringToInt64 ( func :: CastStringToInt64 )) BinaryFunc :: AddInt64 ) ] ) . project ( vec! [ 3 4 5 6 ] ) . let mut expected_optimized = MapFilterProject :: new ( 5 ) . map ( vec! [ MirScalarExpr :: column ( 0 ) . call_unary ( UnaryFunc :: CastStringToInt64 ( func :: CastStringToInt64 )) MirScalarExpr :: column ( 1 ) . call_unary ( UnaryFunc :: CastStringToInt64 ( func :: CastStringToInt64 )) MirScalarExpr :: column ( 5 ) . call_binary ( MirScalarExpr :: column ( 6 ) BinaryFunc :: AddInt64 ) MirScalarExpr :: column ( 7 ) MirScalarExpr :: column ( 2 ) . call_unary ( UnaryFunc :: CastStringToInt64 ( func :: CastStringToInt64 )) MirScalarExpr :: column ( 6 ) . call_binary ( MirScalarExpr :: column ( 9 ) BinaryFunc :: AddInt64 ) MirScalarExpr :: column ( 10 ) ] ) . project ( vec! [ 3 4 8 11 ] ) . Memoize expressions ensuring uniqueness of each ` MirScalarExpr ` . Expressions may not be memoized if they are not certain to be evaluated for example if they occur in conditional branches of a ` MirScalarExpr :: If ` . ` ` ` rust use expr :: { MapFilterProject MirScalarExpr UnaryFunc BinaryFunc } ; Demonstrate extraction of unconditionally evaluated expressions as well as the non - extraction of common expressions guarded by conditions . let mut map_filter_project = MapFilterProject :: new ( 2 ) . map ( vec! [ MirScalarExpr :: If { cond : Box :: new ( MirScalarExpr :: column ( 0 ) . call_binary ( MirScalarExpr :: column ( 1 ) BinaryFunc :: Lt )) then : Box :: new ( MirScalarExpr :: column ( 0 ) . call_binary ( MirScalarExpr :: column ( 1 ) BinaryFunc :: DivInt64 )) els : Box :: new ( MirScalarExpr :: column ( 1 ) . call_binary ( MirScalarExpr :: column ( 0 ) BinaryFunc :: DivInt64 )) } MirScalarExpr :: If { cond : Box :: new ( MirScalarExpr :: column ( 0 ) . call_binary ( MirScalarExpr :: column ( 1 ) BinaryFunc :: Lt )) then : Box :: new ( MirScalarExpr :: column ( 1 ) . call_binary ( MirScalarExpr :: column ( 0 ) BinaryFunc :: DivInt64 )) els : Box :: new ( MirScalarExpr :: column ( 0 ) . call_binary ( MirScalarExpr :: column ( 1 ) BinaryFunc :: DivInt64 )) } ] ) . let mut expected_optimized = MapFilterProject :: new ( 2 ) . map ( vec! [ MirScalarExpr :: column ( 0 ) . call_binary ( MirScalarExpr :: column ( 1 ) BinaryFunc :: Lt ) MirScalarExpr :: If { cond : Box :: new ( MirScalarExpr :: column ( 2 )) then : Box :: new ( MirScalarExpr :: column ( 0 ) . call_binary ( MirScalarExpr :: column ( 1 ) BinaryFunc :: DivInt64 )) els : Box :: new ( MirScalarExpr :: column ( 1 ) . call_binary ( MirScalarExpr :: column ( 0 ) BinaryFunc :: DivInt64 )) } MirScalarExpr :: column ( 3 ) MirScalarExpr :: If { cond : Box :: new ( MirScalarExpr :: column ( 2 )) then : Box :: new ( MirScalarExpr :: column ( 1 ) . call_binary ( MirScalarExpr :: column ( 0 ) BinaryFunc :: DivInt64 )) els : Box :: new ( MirScalarExpr :: column ( 0 ) . call_binary ( MirScalarExpr :: column ( 1 ) BinaryFunc :: DivInt64 )) } MirScalarExpr :: column ( 5 ) ] ) . project ( vec! [ 0 1 4 6 ] ) . Memoize expressions ensuring uniqueness of each ` MirScalarExpr ` .