1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
//! Component trait implementations
//!
//! Each component represents an abstract computation.
//! Example components are Materialize for loading a dataframe, Index for retrieving specific columns from the dataframe, Mean for aggregating data, LaplaceMechanism for privatizing data, etc.
//!
//! There are a set of possible behaviours each component may implement. Each behavior corresponds to a trait.
//! The only trait in the runtime is the Evaluable trait.
//!
//! Implementations of the Evaluable trait are distributed among the module files.

use smartnoise_validator::errors::*;
use crate::NodeArguments;
use smartnoise_validator::base::ReleaseNode;

use smartnoise_validator::proto;

//pub mod bin;
pub mod cast;
pub mod clamp;
pub mod count;
pub mod covariance;
pub mod column_bind;
pub mod digitize;
pub mod dp_gumbel_median;
pub mod filter;
pub mod histogram;
pub mod impute;
pub mod index;
// pub mod linreg_noisy_stats;
pub mod materialize;
pub mod mean;
pub mod mechanisms;
pub mod partition;
pub mod quantile;
pub mod raw_moment;
pub mod reshape;
pub mod resize;
pub mod sum;
pub mod theil_sen;
pub mod to_dataframe;
pub mod transforms;
pub mod union;
pub mod variance;

/// Evaluable component trait
///
/// Evaluable structs represent an abstract computation.
pub trait Evaluable {
    /// The concrete implementation of the abstract computation that the struct represents.
    ///
    /// # Arguments
    /// * `privacy_definition` - the definition of privacy under which the computation takes place
    /// * `arguments` - a hashmap, where the `String` keys are the names of arguments, and the `Value` values are the data inputs
    ///
    /// # Returns
    /// The concrete value corresponding to the abstract computation that the struct represents
    fn evaluate(
        &self,
        privacy_definition: &Option<proto::PrivacyDefinition>,
        arguments: NodeArguments
    ) -> Result<ReleaseNode>;
}

impl Evaluable for proto::component::Variant {
    /// Utility implementation on the enum containing all variants of a component.
    ///
    /// This utility delegates evaluation to the concrete implementation of each component variant.
    fn evaluate(
        &self,
        privacy_definition: &Option<proto::PrivacyDefinition>,
        arguments: NodeArguments
    ) -> Result<ReleaseNode> {
        macro_rules! evaluate {
            ($( $variant:ident ),*) => {
                {
                    $(
                       if let proto::component::Variant::$variant(x) = self {
                            return x.evaluate(privacy_definition, arguments)
                                .chain_err(|| format!("node specification: {:?}:", self))
                       }
                    )*
                }
            }
        }

        evaluate!(
            // INSERT COMPONENT LIST
            Cast, Clamp, ColumnBind, Count, Covariance, Digitize, Filter, Histogram, Impute, Index,
            Materialize, Mean, Partition,
            Quantile, RawMoment, Reshape, Resize, Sum, ToDataframe, Union, Variance,

            ExponentialMechanism, GaussianMechanism,
            LaplaceMechanism, SnappingMechanism,
            SimpleGeometricMechanism,

            Abs, Add, LogicalAnd, Divide, Equal, GreaterThan, LessThan, Log, Modulo, Multiply,
            Negate, Negative, LogicalOr, Power, RowMax, RowMin, Subtract, TheilSen, DpGumbelMedian
        );

        Err(format!("Component type not implemented: {:?}", self).into())
    }
}