prepare for the restoration of validity

main
Ziyang Hu 2 years ago
parent f14a46552c
commit 09f578d085

@ -58,14 +58,16 @@ fixed_arg = _{fixed_rel | fixed_opt_pair}
fixed_opt_pair = {ident ~ ":" ~ expr}
fixed_rel = {fixed_rule_rel | fixed_relation_rel | fixed_named_relation_rel }
fixed_rule_rel = {ident ~ "[" ~ (var ~ ",")* ~ var? ~ "]"}
fixed_relation_rel = {relation_ident ~ "[" ~ (var ~ ",")* ~ var? ~ "]"}
fixed_named_relation_rel = {relation_ident ~ "{" ~ (fixed_named_relation_arg_pair ~ ",")* ~ fixed_named_relation_arg_pair? ~ "}"}
fixed_relation_rel = {relation_ident ~ "[" ~ (var ~ ",")* ~ var? ~ validity_clause? ~ "]"}
fixed_named_relation_rel = {relation_ident ~ "{" ~ (fixed_named_relation_arg_pair ~ ",")* ~ fixed_named_relation_arg_pair? ~ validity_clause? ~ "}"}
fixed_named_relation_arg_pair = {ident ~ (":" ~ ident)?}
validity_clause = {"@" ~ expr}
rule_body = {(disjunction ~ ",")* ~ disjunction?}
rule_apply = {underscore_ident ~ "[" ~ apply_args ~ "]"}
relation_named_apply = {relation_ident ~ "{" ~ named_apply_args ~ "}"}
relation_apply = {relation_ident ~ "[" ~ apply_args ~ "]"}
relation_named_apply = {relation_ident ~ "{" ~ named_apply_args ~ validity_clause? ~ "}"}
relation_apply = {relation_ident ~ "[" ~ apply_args ~ validity_clause? ~ "]"}
disjunction = {(atom ~ "or" )* ~ atom}
atom = _{ negation | relation_named_apply | relation_apply | rule_apply | unify_multi | unify | expr | grouped}

@ -1271,6 +1271,7 @@ pub(crate) fn op_to_bool(args: &[DataValue]) -> Result<DataValue> {
DataValue::Regex(r) => !r.0.as_str().is_empty(),
DataValue::List(l) => !l.is_empty(),
DataValue::Set(s) => !s.is_empty(),
DataValue::Validity(vld) => vld.is_assert,
DataValue::Bot => false,
}))
}
@ -1288,6 +1289,7 @@ pub(crate) fn op_to_unity(args: &[DataValue]) -> Result<DataValue> {
DataValue::Regex(r) => if r.0.as_str().is_empty() {0 } else { 1},
DataValue::List(l) => if l.is_empty() {0} else {1},
DataValue::Set(s) => if s.is_empty() {0} else {1},
DataValue::Validity(vld) => if vld.is_assert {1} else {0},
DataValue::Bot => 0,
}))
}

@ -29,7 +29,9 @@ impl From<JsonValue> for DataValue {
JsonValue::Object(d) => DataValue::List(
d.into_iter()
.map(|(k, v)| {
DataValue::List([DataValue::Str(SmartString::from(k)), DataValue::from(v)].into())
DataValue::List(
[DataValue::Str(SmartString::from(k)), DataValue::from(v)].into(),
)
})
.collect(),
),
@ -98,6 +100,9 @@ impl From<DataValue> for JsonValue {
DataValue::Uuid(u) => {
json!(u.0)
}
DataValue::Validity(v) => {
json!([v.timestamp.0, v.is_assert])
}
}
}
}

@ -6,6 +6,7 @@
* You can obtain one at https://mozilla.org/MPL/2.0/.
*/
use std::cmp::Reverse;
use std::collections::BTreeSet;
use std::io::Write;
use std::str::FromStr;
@ -13,7 +14,7 @@ use std::str::FromStr;
use byteorder::{BigEndian, ByteOrder, WriteBytesExt};
use regex::Regex;
use crate::data::value::{DataValue, Num, RegexWrapper, UuidWrapper};
use crate::data::value::{DataValue, Num, RegexWrapper, UuidWrapper, Validity};
const INIT_TAG: u8 = 0x00;
const NULL_TAG: u8 = 0x01;
@ -26,6 +27,7 @@ const UUID_TAG: u8 = 0x08;
const REGEX_TAG: u8 = 0x09;
const LIST_TAG: u8 = 0x0A;
const SET_TAG: u8 = 0x0B;
const VLD_TAG: u8 = 0x0C;
const BOT_TAG: u8 = 0xFF;
const IS_FLOAT: u8 = 0b00010000;
@ -78,6 +80,14 @@ pub(crate) trait MemCmpEncoder: Write {
}
self.write_u8(INIT_TAG).unwrap()
}
DataValue::Validity(vld) => {
let ts = vld.timestamp.0;
let ts_u64 = order_encode_i64(ts);
let ts_flipped = !ts_u64;
self.write_u8(VLD_TAG).unwrap();
self.write_u64::<BigEndian>(ts_flipped).unwrap();
self.write_u8(vld.is_assert as u8).unwrap();
}
DataValue::Bot => self.write_u8(BOT_TAG).unwrap(),
}
}
@ -269,6 +279,21 @@ impl DataValue {
}
(DataValue::Set(collected), &remaining[1..])
}
VLD_TAG => {
let (ts_flipped_bytes, rest) = remaining.split_at(8);
let ts_flipped = BigEndian::read_u64(ts_flipped_bytes);
let ts_u64 = !ts_flipped;
let ts = order_decode_i64(ts_u64);
let (is_assert_byte, rest) = rest.split_first().unwrap();
let is_assert = *is_assert_byte != 0;
(
DataValue::Validity(Validity {
timestamp: Reverse(ts),
is_assert,
}),
rest,
)
}
BOT_TAG => (DataValue::Bot, remaining),
_ => unreachable!("{:?}", bs),
}

@ -324,11 +324,13 @@ pub(crate) enum FixedRuleArg {
Stored {
name: Symbol,
bindings: Vec<Symbol>,
// valid_at: Option<Expr>,
span: SourceSpan,
},
NamedStored {
name: Symbol,
bindings: BTreeMap<SmartString<LazyCompact>, Symbol>,
// valid_at: Option<Expr>,
span: SourceSpan,
},
}
@ -998,6 +1000,7 @@ pub(crate) struct InputNamedFieldRelationApplyAtom {
pub(crate) struct InputRelationApplyAtom {
pub(crate) name: Symbol,
pub(crate) args: Vec<Expr>,
// pub(crate) valid_at: Option<Expr>,
pub(crate) span: SourceSpan,
}

@ -6,7 +6,7 @@
* You can obtain one at https://mozilla.org/MPL/2.0/.
*/
use std::cmp::Ordering;
use std::cmp::{Ordering, Reverse};
use std::collections::BTreeSet;
use std::fmt::{Debug, Display, Formatter};
use std::hash::{Hash, Hasher};
@ -84,6 +84,22 @@ impl PartialOrd for RegexWrapper {
}
}
#[derive(
Copy,
Clone,
Eq,
PartialEq,
Ord,
PartialOrd,
serde_derive::Deserialize,
serde_derive::Serialize,
Hash,
)]
pub struct Validity {
pub(crate) timestamp: Reverse<i64>,
pub(crate) is_assert: bool,
}
#[derive(
Clone, PartialEq, Eq, PartialOrd, Ord, serde_derive::Deserialize, serde_derive::Serialize, Hash,
)]
@ -98,6 +114,7 @@ pub enum DataValue {
Regex(RegexWrapper),
List(Vec<DataValue>),
Set(BTreeSet<DataValue>),
Validity(Validity),
Bot,
}
@ -245,6 +262,11 @@ impl Display for DataValue {
DataValue::List(ls) => f.debug_list().entries(ls).finish(),
DataValue::Set(s) => f.debug_list().entries(s).finish(),
DataValue::Bot => write!(f, "null"),
DataValue::Validity(v) => f
.debug_struct("Validity")
.field("timestamp", &v.timestamp.0)
.field("retracted", &v.is_assert)
.finish(),
}
}
}

@ -560,6 +560,10 @@ fn parse_atom(src: Pair<'_>, param_pool: &BTreeMap<String, DataValue>) -> Result
.into_inner()
.map(|v| build_expr(v, param_pool))
.try_collect()?;
// let validity = match src.next() {
// None => None,
// Some(vld_clause) => todo!()
// };
InputAtom::Relation {
inner: InputRelationApplyAtom {
name: Symbol::new(&name.as_str()[1..], name.extract_span()),
@ -591,6 +595,10 @@ fn parse_atom(src: Pair<'_>, param_pool: &BTreeMap<String, DataValue>) -> Result
Ok((name, arg))
})
.try_collect()?;
// let validity = match src.next() {
// None => None,
// Some(vld_clause) => todo!()
// };
InputAtom::NamedFieldRelation {
inner: InputNamedFieldRelationApplyAtom { name, args, span },
}
@ -698,9 +706,16 @@ fn parse_fixed_rule(
Rule::fixed_relation_rel => {
let mut els = inner.into_inner();
let name = els.next().unwrap();
let bindings = els
.map(|v| Symbol::new(v.as_str(), v.extract_span()))
.collect_vec();
let mut bindings = vec![];
for v in els {
match v.as_rule() {
Rule::var => {
bindings.push(Symbol::new(v.as_str(), v.extract_span()))
}
Rule::validity_clause => todo!(),
_ => unreachable!(),
}
}
rule_args.push(FixedRuleArg::Stored {
name: Symbol::new(
name.as_str().strip_prefix('*').unwrap(),
@ -713,18 +728,23 @@ fn parse_fixed_rule(
Rule::fixed_named_relation_rel => {
let mut els = inner.into_inner();
let name = els.next().unwrap();
let bindings = els
.map(|v| {
let mut vs = v.into_inner();
let kp = vs.next().unwrap();
let k = SmartString::from(kp.as_str());
let v = match vs.next() {
Some(vp) => Symbol::new(vp.as_str(), vp.extract_span()),
None => Symbol::new(k.clone(), kp.extract_span()),
};
(k, v)
})
.collect();
let mut bindings = BTreeMap::new();
for p in els {
match p.as_rule() {
Rule::fixed_named_relation_arg_pair => {
let mut vs = p.into_inner();
let kp = vs.next().unwrap();
let k = SmartString::from(kp.as_str());
let v = match vs.next() {
Some(vp) => Symbol::new(vp.as_str(), vp.extract_span()),
None => Symbol::new(k.clone(), kp.extract_span()),
};
bindings.insert(k, v);
}
Rule::validity_clause => todo!(),
_ => unreachable!(),
}
}
rule_args.push(FixedRuleArg::NamedStored {
name: Symbol::new(

Loading…
Cancel
Save