Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support | as the disjunction token #64

Merged
merged 1 commit into from
Mar 2, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion ascent/examples/ascent_disjunction_clause.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ ascent! {

relation even_or_square(i32);

even_or_square(x) <-- (even(x) || square(x));
even_or_square(x) <-- (even(x) | square(x));
}

fn main() {
Expand Down
1 change: 1 addition & 0 deletions ascent/src/exps.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
// TODO delete this file
#![cfg(all(test, feature = "par"))]
#![allow(dead_code)]

Expand Down
6 changes: 3 additions & 3 deletions ascent_macro/src/ascent_hir.rs
Original file line number Diff line number Diff line change
Expand Up @@ -520,9 +520,9 @@ pub(crate) fn prog_get_relation<'a>(
Err(Error::new(
name.span(),
format!(
"wrong arity for relation `{name}` (expected {expected}, found {actual})",
expected = arity,
actual = rel.field_types.len()
"wrong arity for relation `{name}` (expected {expected}, found {found})",
expected = rel.field_types.len(),
found = arity,
),
))
} else {
Expand Down
19 changes: 16 additions & 3 deletions ascent_macro/src/ascent_syntax.rs
Original file line number Diff line number Diff line change
Expand Up @@ -177,21 +177,34 @@ fn peek_macro_invocation(parse_stream: ParseStream) -> bool {

fn peek_if_or_let(parse_stream: ParseStream) -> bool { parse_stream.peek(Token![if]) || parse_stream.peek(Token![let]) }

#[derive(Parse, Clone)]
enum DisjunctionToken {
#[allow(unused)]
#[peek(Token![||], name = "||")]
OrOr(Token![||]),
#[allow(unused)]
#[peek(Token![|], name = "|")]
Or(Token![|]),
}

#[derive(Clone)]
pub struct DisjunctionNode {
paren: syn::token::Paren,
disjuncts: Punctuated<Punctuated<BodyItemNode, Token![,]>, Token![||]>,
disjuncts: Punctuated<Punctuated<BodyItemNode, Token![,]>, DisjunctionToken>,
}

impl Parse for DisjunctionNode {
fn parse(input: ParseStream) -> Result<Self> {
let content;
let paren = parenthesized!(content in input);
let res: Punctuated<Punctuated<BodyItemNode, Token![,]>, Token![||]> =
Punctuated::<Punctuated<BodyItemNode, Token![,]>, Token![||]>::parse_terminated_with(
let res: Punctuated<Punctuated<BodyItemNode, Token![,]>, DisjunctionToken> =
Punctuated::<Punctuated<BodyItemNode, Token![,]>, DisjunctionToken>::parse_terminated_with(
&content,
Punctuated::<BodyItemNode, Token![,]>::parse_separated_nonempty,
)?;
if res.pairs().any(|pair| matches!(pair.punct(), Some(DisjunctionToken::OrOr(_)))) {
eprintln!("WARNING: In Ascent rules, use `|` as the disjunction token instead of `||`")
}
Ok(DisjunctionNode { paren, disjuncts: res })
}
}
Expand Down
2 changes: 1 addition & 1 deletion ascent_tests/src/analysis_exp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,7 @@ ascent! {

ς(v.clone(), ρ2, a, tick(e, ρ, a, t, k)) <--
ς(?e@Ref(x), ρ, a, t),
(σ(ρ[x], ?Value(v, ρ2)) ||
(σ(ρ[x], ?Value(v, ρ2)) |
σnum(ρ[x], lit), let v = Lit(*lit), let ρ2 = ρ),
σ(a, ?Kont(k));

Expand Down
6 changes: 3 additions & 3 deletions ascent_tests/src/macros_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ fn test_macro_in_macro() {
foo2(12, 11);

macro foo($x: ident, $y: ident){
(foo1($x, $y) || foo2($x, $y)), if $x < $y,
(foo1($x, $y) | foo2($x, $y)), if $x < $y,
}

bar(x, y) <-- foo!(x, y);
Expand Down Expand Up @@ -51,7 +51,7 @@ fn test_macro_in_macro2() {
relation res(Atomic);

macro ae($x: ident) {
(res(?Atomic::Var(_var)), σ(_var, $x) ||
(res(?Atomic::Var(_var)), σ(_var, $x) |
res(?Atomic::Val($x)))
}

Expand Down Expand Up @@ -201,7 +201,7 @@ fn test_macro_in_macro7() {
macro bar($x: ident, $y: expr) { bar(?Some($x), $y) }

macro foo2($x: expr, $y: expr) {
foo!($x, $y), let x = $x, for x2 in [1, 2], ((foo(x, x2), let y = $y, let _ = println!("{}", y)) || if true, for y in [$y, $y]),
foo!($x, $y), let x = $x, for x2 in [1, 2], ((foo(x, x2), let y = $y, let _ = println!("{}", y)) | if true, for y in [$y, $y]),
foo!(x + 0, y - 0), foo(x, y), foo!(x, y),
let z = |x: i32| {x}, foo(z(*x), z(*y))
}
Expand Down
26 changes: 18 additions & 8 deletions ascent_tests/src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -402,24 +402,34 @@ fn test_dl_disjunctions() {
relation bar(i32, i32);

small(x) <-- for x in 0..5;
foo1(0, 4);
foo1(1, 4);
foo1(2, 6);
foo1(0, 4); foo1(1, 4); foo1(2, 6);

foo2(3, 30);
foo2(2, 20);
foo2(8, 21);
foo2(9, 21);
foo2(3, 30); foo2(2, 20); foo2(8, 21); foo2(9, 21);

bar(x.clone(), y.clone()) <-- ((for x in 3..10), small(x) || foo1(x,_y)), (foo2(x,y));

};
let mut prog = AscentProgram::default();
prog.run();
println!("bar: {:?}", prog.bar);
assert_rels_eq!([(3, 30), (2, 20)], prog.bar);
}

#[test]
fn test_dl_disjunctions2() {
let res = ascent_run! {
relation road(&'static str, &'static str);
relation rail(&'static str, &'static str);

road("A", "B"); road("B", "C"); rail("C", "D");

relation connected(&'static str, &'static str);

connected(x, y) <-- (road(x, y) | rail(x, y));
connected(x, z) <-- connected(x, y), (road(y, z) | rail(y, z));
};
assert!(res.connected.contains(&("A", "D")));
}

#[test]
fn test_dl_repeated_vars() {
ascent_m_par! {
Expand Down
Loading