fn visit_exprs_simultaneously(&self, exprs: Vec<Expr>, is_monotonic: Option<bool>, mut model: CausalModel) -> CausalModel {
    let mut op_models = vec![];
    let mut models = vec![];
    for expr in exprs {
      let is_var = expr.is_var();
      let m = self.visit_expr(expr, is_monotonic, model.clone());
      if is_var { op_models.push(m); }
      else { models.push(m); }
    }
    model = model.fold(models);
    assert!(op_models.iter().all(|m| m.latest_ops.len() == 1),
      "visit_exprs_simultaneously: variable operation must only create one latest operation.");
    let simultaneous_ops: Vec<usize> = op_models.iter().map(|m| m.latest_ops[0]).collect();
    model = model.fold(op_models);
    model.add_simultaneous_ops_constraint(simultaneous_ops);
    model
  }
/// Arguments of a function must not be sequentially ordered: it is possible to execute them in any order.
/// For example: `f(read x, write x)` must fail because we cannot sequentially order the write after the read.
/// Constraining operations to be simultaneous enforces that these operations are not sequentially ordered.
Arguments of a function must not be sequentially ordered: it is possible to execute them in any order.
For example: `f(read x, write x)` must fail because we cannot sequentially order the write after the read.
Constraining operations to be simultaneous enforces that these operations are not sequentially ordered.
Arguments of a function must not be sequentially ordered : it is possible to execute them in any order . For example : ` f ( read x write x ) ` must fail because we cannot sequentially order the write after the read . Constraining operations to be simultaneous enforces that these operations are not sequentially ordered .
fn visit_exprs_simultaneously(&self, exprs: Vec<Expr>, is_monotonic: Option<bool>, mut model: CausalModel) -> CausalModel {
    let mut op_models = vec![];
    let mut models = vec![];
    for expr in exprs {
      let is_var = expr.is_var();
      let m = self.visit_expr(expr, is_monotonic, model.clone());
      if is_var { op_models.push(m); }
      else { models.push(m); }
    }
    model = model.fold(models);
    assert!(op_models.iter().all(|m| m.latest_ops.len() == 1),
      "visit_exprs_simultaneously: variable operation must only create one latest operation.");
    let simultaneous_ops: Vec<usize> = op_models.iter().map(|m| m.latest_ops[0]).collect();
    model = model.fold(op_models);
    model.add_simultaneous_ops_constraint(simultaneous_ops);
    model
  }
fn visit_exprs_simultaneously ( & self , exprs : Vec < Expr > , is_monotonic : Option < bool > , mut model : CausalModel ) -> CausalModel { let mut op_models = vec ! [ ] ; let mut models = vec ! [ ] ; for expr in exprs { let is_var = expr . is_var ( ) ; let m = self . visit_expr ( expr , is_monotonic , model . clone ( ) ) ; if is_var { op_models . push ( m ) ; } else { models . push ( m ) ; } } model = model . fold ( models ) ; assert ! ( op_models iter ( ) all ( m m latest_ops len ( ) 1 ) " " ) ; let simultaneous_ops : Vec < usize > = op_models . iter ( ) . map ( | m | m . latest_ops [ 0 ] ) . collect ( ) ; model = model . fold ( op_models ) ; model . add_simultaneous_ops_constraint ( simultaneous_ops ) ; model }
Arguments of a function must not be sequentially ordered: it is possible to execute them in any order.
Arguments of a function must not be sequentially ordered : it is possible to execute them in any order .
&self
exprs
Vec<Expr>
is_monotonic
Option<bool>
model
CausalModel
&self
exprs
Vec<Expr>
is_monotonic
Option<bool>
model
CausalModel