diff --git a/.gitignore b/.gitignore index 40d172f..e3848f8 100644 --- a/.gitignore +++ b/.gitignore @@ -2,7 +2,7 @@ .DS_Store .profile/ -result/ +result .direnv/ target/ diff --git a/src/pipeline/relation.rs b/src/pipeline/relation.rs index 4c9ad3f..ad02456 100644 --- a/src/pipeline/relation.rs +++ b/src/pipeline/relation.rs @@ -58,6 +58,7 @@ pub enum Relation { Correlate(Box, Box), Union(Box, Box), Except(Box, Box), + Intersect(Box, Box), Distinct(Box), Values { schema: Vec, @@ -93,7 +94,7 @@ impl Relation { Join { left, right, .. } | Correlate(left, right) => { left.scope(schemas) + right.scope(schemas) }, - Union(rel1, _) | Except(rel1, _) => rel1.scope(schemas), + Union(rel1, _) | Except(rel1, _) | Intersect(rel1, _) => rel1.scope(schemas), Distinct(rel) => rel.scope(schemas), Values { schema, .. } => schema.clone().into(), Sort { source, .. } => source.scope(schemas), @@ -256,7 +257,7 @@ impl Eval for Env<'_> { let right = Env(schemas, &right_subst, body_lvl).eval(*right); Rel::lam(scopes, UExpr::App(left, left_vars) * UExpr::App(right, right_vars)) }, - // R(x) union S(y) + // R(x) union all S(y) // λx. R(x) + S(x) Union(left, right) => { let body_lvl = lvl + scopes.len(); @@ -265,14 +266,23 @@ impl Eval for Env<'_> { let right = Env(schemas, subst, body_lvl).eval(*right); Rel::lam(scopes, UExpr::App(left, vars.clone()) + UExpr::App(right, vars)) }, + // R(x) intersect S(y) + // λx. ‖R(x) × S(x)‖ + Intersect(left, right) => { + let body_lvl = lvl + scopes.len(); + let vars = vars(lvl, scopes.clone()); + let left = Env(schemas, subst, body_lvl).eval(*left); + let right = Env(schemas, subst, body_lvl).eval(*right); + Rel::lam(scopes, UExpr::squash(UExpr::App(left, vars.clone()) * UExpr::App(right, vars))) + }, // R(x) except S(y) - // λx. R(x) × ¬S(x) + // λx. ‖R(x) × ¬S(x)‖ Except(left, right) => { let body_lvl = lvl + scopes.len(); let vars = vars(lvl, scopes.clone()); let left = Env(schemas, subst, body_lvl).eval(*left); let right = Env(schemas, subst, body_lvl).eval(*right); - Rel::lam(scopes, UExpr::App(left, vars.clone()) * !UExpr::App(right, vars)) + Rel::lam(scopes, UExpr::squash(UExpr::App(left, vars.clone()) * !UExpr::App(right, vars))) }, // Distinct R(x) // λx. ‖R(x)‖