partial evaluation

main
Ziyang Hu 2 years ago
parent b576d0e867
commit b188a5a559

@ -1,4 +1,6 @@
use std::borrow::Cow;
use std::collections::{BTreeMap, HashSet};
use std::path::is_separator;
use std::process::id;
use pest::iterators::{Pair, Pairs};
use cozorocks::{SlicePtr, StatusCode};
@ -190,6 +192,83 @@ pub trait Environment<T: AsRef<[u8]>> where Self: Sized {
}
self.define_data(&name, tuple, in_root)
}
fn partial_eval<'a>(&self, value: Value<'a>) -> Result<(bool, Value<'a>)> {
match value {
v @ (Value::Null |
Value::Bool(_) |
Value::UInt(_) |
Value::Int(_) |
Value::Float(_) |
Value::Uuid(_) |
Value::Text(_) |
Value::EndSentinel) => Ok((true, v)),
Value::List(l) => {
let init_vec = Vec::with_capacity(l.len());
let res: Result<(bool, Vec<Value>)> = l.into_iter()
.try_fold((true, init_vec), |(is_evaluated, mut accum), val| {
let (ev, new_val) = self.partial_eval(val)?;
accum.push(new_val);
Ok((ev && is_evaluated, accum))
});
let (is_ev, v) = res?;
Ok((is_ev, v.into()))
}
Value::Dict(d) => {
let res: Result<(bool, BTreeMap<Cow<str>, Value>)> = d.into_iter()
.try_fold((true, BTreeMap::new()), |(is_evaluated, mut accum), (k, v)| {
let (ev, new_val) = self.partial_eval(v)?;
accum.insert(k, new_val);
Ok((ev && is_evaluated, accum))
});
let (is_ev, v) = res?;
Ok((is_ev, v.into()))
}
Value::Variable(v) => {
Ok(match self.resolve(&v)? {
None => (false, Value::Variable(v)),
Some(rs) => {
match rs.data_kind() {
Ok(DataKind::Value) => {
let resolved = rs.get(0).ok_or_else(|| CozoError::BadDataFormat(rs.data.as_ref().to_vec()))?;
(resolved.is_evaluated(), resolved.to_static())
}
_ => (false, Value::Variable(v))
}
}
})
}
Value::Apply(op, args) => {
use crate::relation::value;
Ok(match op.as_ref() {
value::OP_ADD => add_values(args)?,
value::OP_SUB => sub_values(args)?,
value::OP_MUL => { todo!() }
value::OP_DIV => { todo!() }
value::OP_EQ => { todo!() }
value::OP_NE => { todo!() }
value::OP_OR => { todo!() }
value::OP_AND => { todo!() }
value::OP_MOD => { todo!() }
value::OP_GT => { todo!() }
value::OP_GE => { todo!() }
value::OP_LT => { todo!() }
value::OP_LE => { todo!() }
value::OP_POW => { todo!() }
value::OP_COALESCE => { todo!() }
value::OP_NEGATE => { todo!() }
value::OP_MINUS => { todo!() }
_ => { todo!() }
})
}
}
}
}
fn add_values(args: Vec<Value>) -> Result<(bool, Value)> {
todo!()
}
fn sub_values(args: Vec<Value>) -> Result<(bool, Value)> {
todo!()
}
pub struct MemoryEnv {

@ -23,36 +23,13 @@ pub enum Tag {
Text = 6,
Uuid = 7,
UInt = 8,
List = 9,
Dict = 10,
// Timestamp = 23,
// Datetime = 25,
// Timezone = 27,
// Date = 27,
// Time = 29,
// Duration = 31,
// BigInt = 51,
// BigDecimal = 53,
// Inet = 55,
// Crs = 57,
// BitArr = 60,
// U8Arr = 61,
// I8Arr = 62,
// U16Arr = 63,
// I16Arr = 64,
// U32Arr = 65,
// I32Arr = 66,
// U64Arr = 67,
// I64Arr = 68,
// F16Arr = 69,
// F32Arr = 70,
// F64Arr = 71,
// C32Arr = 72,
// C64Arr = 73,
// C128Arr = 74,
Variable = u8::MAX - 2,
Apply = u8::MAX - 1,
MaxTag = u8::MAX,
List = 128,
Dict = 129,
Variable = 253,
Apply = 254,
MaxTag = 255,
}
impl TryFrom<u8> for Tag {
@ -69,14 +46,43 @@ impl TryFrom<u8> for Tag {
6 => Text,
7 => Uuid,
8 => UInt,
9 => List,
10 => Dict,
u8::MAX => MaxTag,
128 => List,
129 => Dict,
253 => Variable,
254 => Apply,
255 => MaxTag,
v => return Err(v)
})
}
}
// Timestamp = 23,
// Datetime = 25,
// Timezone = 27,
// Date = 27,
// Time = 29,
// Duration = 31,
// BigInt = 51,
// BigDecimal = 53,
// Inet = 55,
// Crs = 57,
// BitArr = 60,
// U8Arr = 61,
// I8Arr = 62,
// U16Arr = 63,
// I16Arr = 64,
// U32Arr = 65,
// I32Arr = 66,
// U64Arr = 67,
// I64Arr = 68,
// F16Arr = 69,
// F32Arr = 70,
// F64Arr = 71,
// C32Arr = 72,
// C64Arr = 73,
// C128Arr = 74,
#[derive(Debug, Clone, PartialEq, Ord, PartialOrd, Eq)]
pub enum Value<'a> {
Null,
@ -324,27 +330,44 @@ lazy_static! {
};
}
pub const OP_ADD: &str = "+";
pub const OP_SUB: &str = "-";
pub const OP_MUL: &str = "*";
pub const OP_DIV: &str = "/";
pub const OP_EQ: &str = "==";
pub const OP_NE: &str = "!=";
pub const OP_OR: &str = "||";
pub const OP_AND: &str = "&&";
pub const OP_MOD: &str = "%";
pub const OP_GT: &str = ">";
pub const OP_GE: &str = ">=";
pub const OP_LT: &str = "<";
pub const OP_LE: &str = "<=";
pub const OP_POW: &str = "**";
pub const OP_COALESCE: &str = "~~";
pub const OP_NEGATE: &str = "!";
pub const OP_MINUS: &str = "--";
fn build_expr_infix<'a>(lhs: Result<Value<'a>>, op: Pair<Rule>, rhs: Result<Value<'a>>) -> Result<Value<'a>> {
let lhs = lhs?;
let rhs = rhs?;
let op = match op.as_rule() {
Rule::op_add => "+",
Rule::op_sub => "-",
Rule::op_mul => "*",
Rule::op_div => "/",
Rule::op_eq => "==",
Rule::op_ne => "!=",
Rule::op_or => "||",
Rule::op_and => "&&",
Rule::op_mod => "%",
Rule::op_gt => ">",
Rule::op_ge => ">=",
Rule::op_lt => "<",
Rule::op_le => "<=",
Rule::op_pow => "**",
Rule::op_coalesce => "~~",
Rule::op_add => OP_ADD,
Rule::op_sub => OP_SUB,
Rule::op_mul => OP_MUL,
Rule::op_div => OP_DIV,
Rule::op_eq => OP_EQ,
Rule::op_ne => OP_NE,
Rule::op_or => OP_OR,
Rule::op_and => OP_AND,
Rule::op_mod => OP_MOD,
Rule::op_gt => OP_GT,
Rule::op_ge => OP_GE,
Rule::op_lt => OP_LT,
Rule::op_le => OP_LE,
Rule::op_pow => OP_POW,
Rule::op_coalesce => OP_COALESCE,
_ => unreachable!()
};
Ok(Value::Apply(op.into(), vec![lhs, rhs]))
@ -362,8 +385,8 @@ fn build_expr_primary(pair: Pair<Rule>) -> Result<Value> {
let op = inner.next().unwrap().as_rule();
let term = build_expr_primary(inner.next().unwrap())?;
let op = match op {
Rule::negate => "!",
Rule::minus => "--",
Rule::negate => OP_NEGATE,
Rule::minus => OP_MINUS,
_ => unreachable!()
};
Ok(Value::Apply(op.into(), vec![term]))

Loading…
Cancel
Save