use crate::*;
use std::cell::RefCell;
use std::rc::Rc;
use std::fmt::*;
use num_traits::*;
#[cfg(feature = "parallel")]
use rayon::prelude::*;
use std::thread;
lazy_static! {
pub static ref COLUMN: u64 = hash_str("column");
pub static ref ROW: u64 = hash_str("row");
pub static ref TABLE: u64 = hash_str("table");
pub static ref SET_ANY: u64 = hash_str("set/any");
pub static ref SET_ALL: u64 = hash_str("set/all");
pub static ref SET_CARTESIAN: u64 = hash_str("set/cartesian");
}
#[derive(Debug)]
pub struct SetAnyCol {
pub col: ColumnV<bool>, pub out: ColumnV<bool>
}
impl MechFunction for SetAnyCol {
fn solve(&self) {
let result = self.col.borrow().iter().any(|x| *x == true);
self.out.borrow_mut()[0] = result
}
fn to_string(&self) -> String { format!("{:#?}", self)}
}
#[derive(Debug)]
pub struct SetAllCol {
pub col: ColumnV<bool>, pub out: ColumnV<bool>
}
impl MechFunction for SetAllCol {
fn solve(&self) {
let result = self.col.borrow().iter().all(|x| *x == true);
self.out.borrow_mut()[0] = result
}
fn to_string(&self) -> String { format!("{:#?}", self)}
}
#[derive(Debug)]
pub struct SetAllRow {
pub arg: TableRef, pub out: ColumnV<bool>
}
impl MechFunction for SetAllRow {
fn solve(&self) {
let arg_brrw = self.arg.borrow();
for ix in 0..arg_brrw.rows {
let mut all = true;
for iy in 0..arg_brrw.cols {
let value = match (arg_brrw.get_raw(ix,iy), all) {
(Ok(Value::Bool(true)),true) => true,
_ => false,
};
all = value;
}
self.out.borrow_mut()[ix] = all;
}
}
fn to_string(&self) -> String { format!("{:#?}", self)}
}
#[derive(Debug)]
pub struct SetAllTable {
pub arg: TableRef, pub out: ColumnV<bool>
}
impl MechFunction for SetAllTable {
fn solve(&self) {
let mut all = true;
let arg_brrw = self.arg.borrow();
for ix in 0..arg_brrw.cols {
match arg_brrw.get_column_unchecked(ix) {
Column::Bool(col) => {
let result = col.borrow().iter().all(|x| *x == true);
if result == false {
all = false
}
}
_ => (),
}
}
self.out.borrow_mut()[0] = all;
}
fn to_string(&self) -> String { format!("{:#?}", self)}
}
pub struct SetAll{}
impl MechFunctionCompiler for SetAll {
fn compile(&self, block: &mut Block, arguments: &Vec<Argument>, out: &(TableId, TableIndex, TableIndex)) -> std::result::Result<(),MechError> {
let (arg_name, mut arg_column,_) = block.get_arg_columns(arguments)?[0].clone();
let (out_table_id, _, _) = out;
let out_table = block.get_table(out_table_id)?;
let out_col = {
let mut out_brrw = out_table.borrow_mut();
out_brrw.resize(1,1);
out_brrw.set_kind(ValueKind::Bool);
out_brrw.get_column_unchecked(0)
};
if arg_name == *COLUMN {
match (arg_column,out_col) {
(Column::Bool(col),Column::Bool(out)) => block.plan.push(SetAllCol{col: col.clone(), out: out.clone()}),
x => {return Err(MechError{tokens: vec![], msg: "".to_string(), id: 4687, kind: MechErrorKind::GenericError(format!("{:?}", x))});},
}
} else if arg_name == *ROW {
let (_,arg_table_id,_) = &arguments[0];
let arg_table = block.get_table(arg_table_id)?;
let arg_kind = {
let arg_table_brrw = arg_table.borrow();
arg_table_brrw.kind()
};
match (arg_kind,out_col) {
(ValueKind::Bool,Column::Bool(out)) => block.plan.push(SetAllRow{arg: arg_table.clone(), out: out.clone()}),
x => {return Err(MechError{tokens: vec![], msg: "".to_string(), id: 4688, kind: MechErrorKind::GenericError(format!("{:?}", x))});},
}
} else if arg_name == *TABLE {
let (_,arg_table_id,_) = &arguments[0];
let arg_table = block.get_table(arg_table_id)?;
let arg_kind = {
let arg_table_brrw = arg_table.borrow();
arg_table_brrw.kind()
};
match (arg_kind,out_col) {
(ValueKind::Bool,Column::Bool(out)) => block.plan.push(SetAllTable{arg: arg_table.clone(), out: out.clone()}),
x => {return Err(MechError{tokens: vec![], msg: "".to_string(), id: 4689, kind: MechErrorKind::GenericError(format!("{:?}", x))});},
}
} else {
return Err(MechError{tokens: vec![], msg: "".to_string(), id: 4690, kind: MechErrorKind::GenericError(format!("{:?}", arg_name))});
}
Ok(())
}
}
pub struct SetAny{}
impl MechFunctionCompiler for SetAny {
fn compile(&self, block: &mut Block, arguments: &Vec<Argument>, out: &(TableId, TableIndex, TableIndex)) -> std::result::Result<(),MechError> {
let (arg_name, mut arg_column,_) = block.get_arg_columns(arguments)?[0].clone();
let (out_table_id, _, _) = out;
let out_table = block.get_table(out_table_id)?;
let mut out_brrw = out_table.borrow_mut();
out_brrw.resize(1,1);
out_brrw.set_col_kind(0,ValueKind::Bool);
let out_col = out_brrw.get_column_unchecked(0);
if arg_name == *COLUMN {
match (arg_column,out_col) {
(Column::Bool(col),Column::Bool(out)) => block.plan.push(SetAnyCol{col: col.clone(), out: out.clone()}),
x => {return Err(MechError{tokens: vec![], msg: "".to_string(), id: 4691, kind: MechErrorKind::GenericError(format!("{:?}", x))});},
}
} else {
return Err(MechError{tokens: vec![], msg: "".to_string(), id: 4692, kind: MechErrorKind::GenericError(format!("{:?}", arg_name))});
}
Ok(())
}
}
#[derive(Debug)]
pub struct SetCartLeftV<T> {
pub col: (ColumnV<T>,usize),
pub out: ColumnV<T>
}
impl<T> MechFunction for SetCartLeftV<T>
where T: Copy + Debug + Clone + Sync + Send,
{
fn solve(&self) {
let (col,len) = &self.col;
let col_brrw = col.borrow();
col_brrw.iter().flat_map(|n| std::iter::repeat(n).take(*len))
.zip(self.out.borrow_mut().iter_mut())
.for_each(|(c,o)| *o = *c);
}
fn to_string(&self) -> String { format!("{:#?}", self)}
}
#[derive(Debug)]
pub struct SetCartRightV<T> {
pub col: ColumnV<T>,
pub out: ColumnV<T>
}
impl<T> MechFunction for SetCartRightV<T>
where T: Copy + Debug + Clone + Sync + Send,
{
fn solve(&self) {
self.out.borrow_mut()
.iter_mut()
.zip(self.col.borrow().iter().cycle())
.for_each(|(out,col)| *out = *col);
}
fn to_string(&self) -> String { format!("{:#?}", self)}
}
pub struct SetCartesian{}
impl MechFunctionCompiler for SetCartesian {
fn compile(&self, block: &mut Block, arguments: &Vec<Argument>, out: &(TableId, TableIndex, TableIndex)) -> std::result::Result<(),MechError> {
let (_, mut lhs_arg_column,_) = block.get_arg_columns(arguments)?[0].clone();
let (_, mut rhs_arg_column,_) = block.get_arg_columns(arguments)?[1].clone();
let (out_table_id, _, _) = out;
let out_table = block.get_table(out_table_id)?;
let mut out_brrw = out_table.borrow_mut();
let arg_dims = block.get_arg_dims(&arguments)?;
match (&arg_dims[0],&arg_dims[1]) {
(TableShape::Column(rows_left), TableShape::Column(rows_right)) => {
out_brrw.resize(rows_left * rows_right, 2);
out_brrw.set_col_kind(0,lhs_arg_column.kind());
out_brrw.set_col_kind(1,rhs_arg_column.kind());
let out_left_col = out_brrw.get_column_unchecked(0);
match (lhs_arg_column,out_left_col) {
(Column::F32(col),Column::F32(out)) => block.plan.push(SetCartLeftV{col: (col.clone(), *rows_right), out: out.clone()}),
x => {return Err(MechError{tokens: vec![], msg: "".to_string(), id: 4693, kind: MechErrorKind::GenericError(format!("{:?}", x))});},
}
let out_right_col = out_brrw.get_column_unchecked(1);
match (rhs_arg_column,out_right_col) {
(Column::F32(col),Column::F32(out)) => block.plan.push(SetCartRightV{col: col.clone(), out: out.clone()}),
x => {return Err(MechError{tokens: vec![], msg: "".to_string(), id: 4694, kind: MechErrorKind::GenericError(format!("{:?}", x))});},
}
}
x => {return Err(MechError{tokens: vec![], msg: "".to_string(), id: 4695, kind: MechErrorKind::GenericError(format!("{:?}", x))});},
}
Ok(())
}
}