Git Product home page Git Product logo

ascent's People

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar

ascent's Issues

Lattice constrains not enforced on input in ascent_run

The following fails in 0.5.0:

 assert_eq!(ascent_run! {
        lattice a(i64) = vec![(0,),(1,)];
    }.a, vec![(1,)]);

Presumably because the lattice joins are not executed on the incoming vector, as it is seen as 'input'
I think it would make sense to generate an intermediate input relation, so the lattice's rules are upheld.

MISP computation

Hello!

Could you point me where in this repository's code do you compute the optimal solution to the input program's MISP, as described in Subotič et al's "Automatic Index Selection for Large-Scale Datalog Computation"?

From what I understood, HIR transforms each program's rule to a relational form, and then MIR...maps it to primitive searches?

Compiling ascent at runtime

Is there any way I can make the ascent embedded program dynamically generated?
Would there be an internal function that might help, even if not part of the user-facing API?

Thanks!

Calling run() multiple times

If I understand correctly, ascent is't a 'differential datalog'-style implementation, but is optimized for batch processing.
The API does however allow .run() to be called multiple times, so users will eventually do it.
I did a little experiment:

use std::time::Instant;

use ascent::ascent;

fn main() {
    ascent!{
        #![measure_rule_times]
        relation x(u64,u64);
        relation y(u64,u64);
        y(i,n) <-- x(i,n), x(i,n+100);
        x(i,n+200) <-- y(i,n), if *n < 400000;  
    }
    let mut prog = AscentProgram::default();
    fn time(prog: &mut AscentProgram, title: &str) {
        let start = Instant::now();
        prog.run();
        println!("{:?} {:?}", prog.x.len(), prog.y.len());
        println!("{}", prog.scc_times_summary());
        println!("{}: {:?}",title, start.elapsed());
    }
    prog.x = vec![(0, 1,), (0, 101,)];
    time(&mut prog, "Initial run");

    prog.x.push((1,1,));    
    time(&mut prog,"Add of non-consequential fact");

    prog.x.push((1,101,));
    time(&mut prog,"Add of consequential fact");

    let mut prog = AscentProgram::default();
    prog.x = vec![(0, 1,), (0, 101,), (1,1,), (1,101)];
    time(&mut prog,"Full rerun");
}

The output is:

4002 4001
scc 0 time: 1.436391002s
  some of rule times: 1.42136186s
  rule x <-- y_indices_none_delta, if ⋯
    time: 4.024887ms
  rule y <-- x_indices_none_delta, x_indices_0_1_total+delta
    time: 2.227919ms
  rule y <-- x_indices_none_total, x_indices_0_1_delta
    time: 1.415109054s
-----------------------------------------

Initial run: 1.436422348s
4003 4001
scc 0 time: 1.443135223s
  some of rule times: 1.42810157s
  rule x <-- y_indices_none_delta, if ⋯
    time: 5.573965ms
  rule y <-- x_indices_none_delta, x_indices_0_1_total+delta
    time: 7.418424ms
  rule y <-- x_indices_none_total, x_indices_0_1_delta
    time: 1.415109181s
-----------------------------------------

Add of non-consequential fact: 9.375828ms
8004 8002
scc 0 time: 11.459918911s
  some of rule times: 11.423892339s
  rule x <-- y_indices_none_delta, if ⋯
    time: 12.857089ms
  rule y <-- x_indices_none_delta, x_indices_0_1_total+delta
    time: 17.993869ms
  rule y <-- x_indices_none_total, x_indices_0_1_delta
    time: 11.393041381s
-----------------------------------------

Add of consequential fact: 10.019436059s
8004 8002
scc 0 time: 3.073175727s
  some of rule times: 3.047507618s
  rule x <-- y_indices_none_delta, if ⋯
    time: 7.811237ms
  rule y <-- x_indices_none_delta, x_indices_0_1_total+delta
    time: 4.606486ms
  rule y <-- x_indices_none_total, x_indices_0_1_delta
    time: 3.035089895s
-----------------------------------------

Full rerun: 3.073211278s

It seems to me that:

  • running after adding to the input relation sometimes (my second run), does a lot less work than a full rerun.
  • at other times, when a lot of new facts were implied by the new fact, it does more work than a full rerun.

While (as I expected), removing facts from relations isn't supported.

 ascent!{
        struct A;
        relation x(u64);
        relation y(u64);
        y(n) <-- x(n);
    }
    let mut prog = A::default();
    prog.x = vec![(1,), (2,)];
    prog.run();
    println!("{:?}", prog.y);
    prog.x = vec![(1,)];
    prog.run();
    println!("{:?}", prog.y)

produces
[(1,), (2,)]
[(1,), (2,)]

My question is, would it be possible to either:

  • add some support for incrmentalized computation, so that you could indicate 'I've added facts to this relation' and 'I've removed facts from this relation', causing some of the indices to be recomputed?
  • prevent the user from calling .run() multiple times, by making run take ownership of the program instead of taking it by mutable reference

New release with parallel Ascent

Looks like parallel Ascent has been merged to the main branch. It would be great to have this feature available in a release on crates.io!

Project's current formatting makes it hard to contribute non-trivial changes

The project's current code formatting suffers from a couple of issues, affect:

tl;dr: For the sake of making contributions hassle-free it would arguably be preferable to revert to Rust's default format (as applied by rustfmt without a custom rustfmt.toml file) and used by >90% of Rust projects.

  1. It uses a non-standard format

    The Rust project recommends using the default formatting configuration to ease collaboration.

  2. It provides a custom rustfmt.toml file but doesn't actually use it

    While the project provides a rustfmt.toml file

    ./rustfmt.toml

    # https://github.com/rust-lang/rustfmt/blob/master/Configurations.md
    tab_spaces = 3
    fn_call_width = 120
    chain_width = 120
    max_width = 120
    fn_single_line = true

    Running cargo fmt results in 30+ reformatted files, which should not happen if the code had previously been formatted with it.

    As such it is currently impossible to have rustfmt/cargo fmt apply the same formatting as used by the project. And anybody opening a PR on the project gets a nasty surprise when they notice that their IDE auto-formatted the code (as is usually desirable) and now the semantic changes are lost in thousands of formatting changes (as it just happened to me, again).

  3. The rustfmt.toml file requires nightly and is also invalid

    Further more running cargo fmt results in a bunch of warnings:

    $ cargo fmt
    
    Warning: can't set `fn_single_line = true`, unstable features are only available in nightly channel.
    Warning: can't set `fn_single_line = true`, unstable features are only available in nightly channel.
    `fn_call_width` cannot have a value that exceeds `max_width`. `fn_call_width` will be set to the same value as `max_width`
    `chain_width` cannot have a value that exceeds `max_width`. `chain_width` will be set to the same value as `max_width`
    Warning: can't set `fn_single_line = true`, unstable features are only available in nightly channel.
    `fn_call_width` cannot have a value that exceeds `max_width`. `fn_call_width` will be set to the same value as `max_width`
    `chain_width` cannot have a value that exceeds `max_width`. `chain_width` will be set to the same value as `max_width`
    `fn_call_width` cannot have a value that exceeds `max_width`. `fn_call_width` will be set to the same value as `max_width`
    `chain_width` cannot have a value that exceeds `max_width`. `chain_width` will be set to the same value as `max_width`
    `fn_call_width` cannot have a value that exceeds `max_width`. `fn_call_width` will be set to the same value as `max_width`
    `chain_width` cannot have a value that exceeds `max_width`. `chain_width` will be set to the same value as `max_width`
    `fn_call_width` cannot have a value that exceeds `max_width`. `fn_call_width` will be set to the same value as `max_width`
    `chain_width` cannot have a value that exceeds `max_width`. `chain_width` will be set to the same value as `max_width`
    
  4. The project mixes CRLF and LF

    • 37 files use CRLF
    • 31 use LF.

Mimalloc?

Hi! Thank you for writing this library. It is awesome.

I've run into something weird which is probably not even an issue with ascent– crates.io shows mimalloc as a dependency of ascent, even though it doesn't appear in any of the Cargo.toml files in the workspace: https://crates.io/crates/ascent/0.2.0/dependencies

Screen Shot 2022-05-10 at 10 47 39 AM

Any ideas?

Ascent should omit trait bounds on the generated program's type declaration

For generic programs ascent currently requires something along the following:

ascent! {
    pub struct AscentProgram<T: Clone + Eq + Hash>;

    relation dummy(T);

    // ...
}

or

ascent! {
    pub struct AscentProgram<T> where T: Clone + Eq + Hash;

    relation dummy(T);

    // ...
}

which then generates code that looks something like this:

pub struct AscentProgram<T>
where
    T: Clone + Eq + Hash,
{
    pub dummy: Vec<(T,), Global>,

    // ...
}

impl<T> AscentProgram<T>
where
    T: Clone + Eq + Hash,
{
    pub fn run(&mut self){
        // ...
    }

    // ...
}

// ...

This unfortunately tends to lead to problems with rather nasty effects one one's code and is thus generally considered an anti-pattern.

As such the official Rust API guidelines has a chapter on the topic (it talks specifically about derived trait bounds, but the viral breaking change effect is not limited to derived traits):

Data structures do not duplicate derived trait bounds

Generic data structures should not use trait bounds that can be derived or do not otherwise add semantic value. […]

// Prefer this:
#[derive(Clone, Debug, PartialEq)]
struct Good<T> { /* ... */ }

// Over this:
#[derive(Clone, Debug, PartialEq)]
struct Bad<T: Clone + Debug + PartialEq> { /* ... */ }

Generally speaking, adding a trait bound to a data structure is a breaking change because every consumer of that structure will need to start satisfying the additional bound. […]

There is a grey area around other non-derivable trait bounds that are not strictly required by the structure definition, like Read or Write. They may communicate the intended behavior of the type better in its definition but also limits future extensibility. Including semantically useful trait bounds on data structures is still less problematic than including derivable traits as bounds. […]

In short the problem is that trait bounds attached to a type's declaration spread virally (i.e. they require your surrounding code to now also be bounded by these traits), while those only attached to a type's implementation generally don't.

As such the generated code should preferably look like this instead:

pub struct AscentProgram<T>
// notice the lack of a where clause here!
{
    pub dummy: Vec<(T,), Global>,

    // ...
}

impl<T> AscentProgram<T>
where
    T: Clone + Eq + Hash,
{
    pub fn run(&mut self){
        // ...
    }

    // ...
}

// ...

This change should have no affect on ascent itself, but make integrating it much more pleasant and less intrusive.

Incorrect result?

Hi guys,

Consider the following program:

use ascent::ascent;
ascent!{
	relation a__(i32, i32);
	relation c__(i32, i32, i32);
	relation e__(i32);
	relation h__(i32, i32, i32);

	e__(a) <-- a__(b, a);
	h__(e, e, e) <-- a__(d, e), c__(e, f, e), e__(e);

}

fn main() {
	let mut prog = AscentProgram::default();
	prog.a__ = vec![(88,5), (37,24), (11,91)];
	prog.c__ = vec![(32,83,88), (2,8,5)];
	prog.e__ = vec![(44,), (83,)];
	prog.h__ = vec![(38,88,18), (76,18,65), (86,73,91), (98,26,91), (76,10,14)];

	prog.run();
	println!("{:?}", prog.h__);
}

If I run the program, I get the following for the relation h__:
[(38, 88, 18), (76, 18, 65), (86, 73, 91), (98, 26, 91), (76, 10, 14), (5, 5, 5)]

Now, if I add a subgoal c__(e, a, e) in the rule for h__ to get the following new program:

use ascent::ascent;
ascent!{
	relation a__(i32, i32);
	relation c__(i32, i32, i32);
	relation e__(i32);
	relation h__(i32, i32, i32);


	e__(a) <-- a__(b, a);
	h__(e, e, e) <-- a__(d, e), c__(e, f, e), e__(e), c__(e, a, e);
}

fn main() {
	let mut prog = AscentProgram::default();
	prog.a__ = vec![(88,5), (37,24), (11,91)];
	prog.c__ = vec![(32,83,88), (2,8,5)];
	prog.e__ = vec![(44,), (83,)];
	prog.h__ = vec![(38,88,18), (76,18,65), (86,73,91), (98,26,91), (76,10,14)];

	prog.run();
	println!("{:?}", prog.h__);
}

The result for h__ changes and I get:
[(38, 88, 18), (76, 18, 65), (86, 73, 91), (98, 26, 91), (76, 10, 14)]
Adding the subgoal c__(e, a, e) should not change the result for relation h__.
The tuple (5, 5, 5) disappears for the second program which should not have appeared for the first program in the first place.

My Cargo.toml file:

[package]
name = "ascent_project"
version = "0.1.0"
edition = "2021"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
ascent = "0.2"

Please let me know if you cannot reproduce this or if I am doing anything wrong.

ascent = "0.2" broke?

Hi @s-arash,

I think something broke upon your latest commit.
Now the instructions in Using Ascent does not work anymore.
I get:

$ cargo run
    Updating crates.io index
   Compiling ascent_base v0.2.1
   Compiling hashbrown v0.12.1
error: type parameters must be declared prior to const parameters
   --> /home/taylorswift/.cargo/registry/src/github.com-1ecc6299db9ec823/ascent_base-0.2.1/src/lattice/product.rs:102:23
    |
102 | impl <const N: usize, T: PartialOrd> PartialOrd for Product<[T; N]> {
    |      -----------------^------------- help: reorder the parameters: lifetimes, then types, then consts: `<T: PartialOrd, const N: usize>`

error: type parameters must be declared prior to const parameters
   --> /home/taylorswift/.cargo/registry/src/github.com-1ecc6299db9ec823/ascent_base-0.2.1/src/lattice/product.rs:134:23
    |
134 | impl <const N: usize, T: Lattice> Lattice for Product<[T; N]> {
    |      -----------------^---------- help: reorder the parameters: lifetimes, then types, then consts: `<T: Lattice, const N: usize>`

error: type parameters must be declared prior to const parameters
   --> /home/taylorswift/.cargo/registry/src/github.com-1ecc6299db9ec823/ascent_base-0.2.1/src/lattice/product.rs:150:23
    |
150 | impl <const N: usize, T: BoundedLattice> BoundedLattice for Product<[T; N]> {
    |      -----------------^----------------- help: reorder the parameters: lifetimes, then types, then consts: `<T: BoundedLattice, const N: usize>`

error: type parameters must be declared prior to const parameters
  --> /home/taylorswift/.cargo/registry/src/github.com-1ecc6299db9ec823/ascent_base-0.2.1/src/lattice/bounded_set.rs:11:43
   |
11 | pub struct BoundedSet<const BOUND: usize, T: PartialEq + Eq + Hash + Ord>(Option<Set<T>>);
   |                      ---------------------^------------------------------ help: reorder the parameters: lifetimes, then types, then consts: `<T: PartialEq + Eq + Hash + Ord, const BOUND: usize>`

error: type parameters must be declared prior to const parameters
  --> /home/taylorswift/.cargo/registry/src/github.com-1ecc6299db9ec823/ascent_base-0.2.1/src/lattice/bounded_set.rs:10:10
   |
10 | #[derive(Clone, PartialEq, Eq, Hash)]
   |          ^^^^^ help: reorder the parameters: lifetimes, then types, then consts: `<T: ::core::clone::Clone + PartialEq + Eq + Hash + Ord, const BOUND: usize>`

error: type parameters must be declared prior to const parameters
  --> /home/taylorswift/.cargo/registry/src/github.com-1ecc6299db9ec823/ascent_base-0.2.1/src/lattice/bounded_set.rs:10:17
   |
10 | #[derive(Clone, PartialEq, Eq, Hash)]
   |                 ^^^^^^^^^ help: reorder the parameters: lifetimes, then types, then consts: `<T: ::core::cmp::PartialEq + PartialEq + Eq + Hash + Ord, const BOUND: usize>`

error: type parameters must be declared prior to const parameters
  --> /home/taylorswift/.cargo/registry/src/github.com-1ecc6299db9ec823/ascent_base-0.2.1/src/lattice/bounded_set.rs:10:28
   |
10 | #[derive(Clone, PartialEq, Eq, Hash)]
   |                            ^^ help: reorder the parameters: lifetimes, then types, then consts: `<T: ::core::cmp::Eq + PartialEq + Eq + Hash + Ord, const BOUND: usize>`

error: type parameters must be declared prior to const parameters
  --> /home/taylorswift/.cargo/registry/src/github.com-1ecc6299db9ec823/ascent_base-0.2.1/src/lattice/bounded_set.rs:10:32
   |
10 | #[derive(Clone, PartialEq, Eq, Hash)]
   |                                ^^^^ help: reorder the parameters: lifetimes, then types, then consts: `<T: ::core::hash::Hash + PartialEq + Eq + Hash + Ord, const BOUND: usize>`

error: type parameters must be declared prior to const parameters
  --> /home/taylorswift/.cargo/registry/src/github.com-1ecc6299db9ec823/ascent_base-0.2.1/src/lattice/bounded_set.rs:14:26
   |
14 | impl<const BOUND: usize, T: PartialEq + Eq + Hash + Ord> Default for BoundedSet<BOUND, T> {
   |     ---------------------^------------------------------ help: reorder the parameters: lifetimes, then types, then consts: `<T: PartialEq + Eq + Hash + Ord, const BOUND: usize>`

error: type parameters must be declared prior to const parameters
  --> /home/taylorswift/.cargo/registry/src/github.com-1ecc6299db9ec823/ascent_base-0.2.1/src/lattice/bounded_set.rs:18:26
   |
18 | impl<const BOUND: usize, T: PartialEq + Eq + Hash + Ord> BoundedSet<BOUND, T> {
   |     ---------------------^------------------------------ help: reorder the parameters: lifetimes, then types, then consts: `<T: PartialEq + Eq + Hash + Ord, const BOUND: usize>`

error: type parameters must be declared prior to const parameters
  --> /home/taylorswift/.cargo/registry/src/github.com-1ecc6299db9ec823/ascent_base-0.2.1/src/lattice/bounded_set.rs:60:26
   |
60 | impl<const BOUND: usize, T: PartialEq + Eq + Hash + Ord> PartialOrd for BoundedSet<BOUND, T> {
   |     ---------------------^------------------------------ help: reorder the parameters: lifetimes, then types, then consts: `<T: PartialEq + Eq + Hash + Ord, const BOUND: usize>`

error: type parameters must be declared prior to const parameters
  --> /home/taylorswift/.cargo/registry/src/github.com-1ecc6299db9ec823/ascent_base-0.2.1/src/lattice/bounded_set.rs:74:26
   |
74 | impl<const BOUND: usize, T: PartialEq + Eq + Hash + Ord> Lattice for BoundedSet<BOUND, T> {
   |     ---------------------^------------------------------ help: reorder the parameters: lifetimes, then types, then consts: `<T: PartialEq + Eq + Hash + Ord, const BOUND: usize>`

error: type parameters must be declared prior to const parameters
   --> /home/taylorswift/.cargo/registry/src/github.com-1ecc6299db9ec823/ascent_base-0.2.1/src/lattice/bounded_set.rs:103:26
    |
103 | impl<const BOUND: usize, T: PartialEq + Eq + Hash + Ord> BoundedLattice for BoundedSet<BOUND, T> {
    |     ---------------------^------------------------------ help: reorder the parameters: lifetimes, then types, then consts: `<T: PartialEq + Eq + Hash + Ord, const BOUND: usize>`

error: could not compile `ascent_base` due to 13 previous errors
warning: build failed, waiting for other jobs to finish...
error: build failed

When i change ascent = "0.2" in Cargo.toml to a previous commit, e.g.
ascent = {git = "https://github.com/s-arash/ascent", rev="da6078289bbf87bcc843d5cd3f079a08a232051c"}
Then everything works fine.

Are you already aware of this problem or am I doing something wrong?

WASM compatibility: `std::time`

The very minimal use of std::time in Ascent unfortunately panics on WASM.

Possible fixes include either a feature flag to gate use of std::time (this is only slightly complicated by run_timeout), or using an alternative library which provides a WASM-safe implementation such as https://github.com/sebcrozet/instant.

Just a thought. If you would prefer a PR for one or the other of these options, let me know. Thanks!

Private type `…` in public interface (error E0446)

When using non-pub types in ascent macros the generated code emits a "private type in public interface (error E0446)" warning that will turn into an error in future versions of Rust.

To reproduce compile this code:

fn main() {
    #[derive(Hash, Eq, PartialEq, Clone)]
    struct PrivateType;

    #[allow(clippy::all)]
    let _ = ascent::ascent_run! {
        // struct Program;

        relation dummy(PrivateType);
    };
}
warning: private type `PrivateType` in public interface (error E0446)
  --> src/main.rs:6:13
   |
6  |       let _ = ascent::ascent_run! {
   |  _____________^
7  | |         // struct Program;
8  | |
9  | |         relation dummy(PrivateType);
10 | |     };
   | |_____^
   |
   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
   = note: for more information, see issue #34537 <https://github.com/rust-lang/rust/issues/34537>
   = note: `#[warn(private_in_public)]` on by default
   = note: this warning originates in the macro `ascent::ascent_run` (in Nightly builds, run with -Z macro-backtrace for more info)

Un-commenting the // struct Program; silences the warning.

I'm not sure if there's a good solution for this (which doesn't get in the way of scenarios for public types), but it might be a good idea to add a note in the docs for this, since the fix might not be obvious immediately?

Comparison to Crepe?

Crepe is another Rust-macro-embedded Datalog-like eDSL. It would be nice to point to it from the README as an alternative, or even better, to provide a short comparison between the two projects.

ascent_macro: Fix minimal versions (by upgrading syn to v1.0.109, itertools to v0.12)

While a bump to >= v2.x would obviously be preferable I'd like to suggest bumping it at least to the highest v1.x version available for the time being.

Deleting Cargo.lock and running cargo minimal-versions check --workspace --all-features --ignore-private -v (crates.io) reveals that ascent_macro is using APIs from syn and itertools that are not available in their versions specified in Cargo.toml

Full terminal log
$ cargo minimal-versions check --workspace --all-features --ignore-private -v                                                                            
(base) 
info: modifying from <SNIP>/ascent/Cargo.toml
info: modifying from <SNIP>/ascent_base/Cargo.toml
info: modifying from <SNIP>/ascent_macro/Cargo.toml
info: running `rustup run nightly cargo update -Z minimal-versions`
warning: virtual workspace defaulting to `resolver = "1"` despite one or more workspace members being on edition 2021 which implies `resolver = "2"`
note: to keep the current resolver, specify `workspace.resolver = "1"` in the workspace root's manifest
note: to use the edition 2021 resolver, specify `workspace.resolver = "2"` in the workspace root's manifest
note: for more details see https://doc.rust-lang.org/cargo/reference/resolver.html#resolver-versions
    Updating crates.io index
info: running `~/.rustup/toolchains/stable-x86_64-apple-darwin/bin/cargo hack check --workspace --all-features`
info: running `cargo check --all-features` on ascent (1/3)
warning: virtual workspace defaulting to `resolver = "1"` despite one or more workspace members being on edition 2021 which implies `resolver = "2"`
note: to keep the current resolver, specify `workspace.resolver = "1"` in the workspace root's manifest
note: to use the edition 2021 resolver, specify `workspace.resolver = "2"` in the workspace root's manifest
note: for more details see https://doc.rust-lang.org/cargo/reference/resolver.html#resolver-versions
    Blocking waiting for file lock on package cache
    Blocking waiting for file lock on package cache
    Blocking waiting for file lock on package cache
   Compiling crossbeam-utils v0.8.7
   Compiling proc-macro2 v1.0.52
   Compiling memoffset v0.6.1
    Checking lazy_static v1.4.0
   Compiling unicode-ident v1.0.0
   Compiling libc v0.2.95
    Checking scopeguard v1.1.0
   Compiling crossbeam-epoch v0.9.5
   Compiling syn v1.0.0
   Compiling unicode-xid v0.2.0
   Compiling ahash v0.8.4
   Compiling indexmap v1.6.2
   Compiling paste v1.0.0
    Checking either v1.0.0
    Checking zerocopy v0.7.3
   Compiling hashbrown v0.9.1
    Checking smallvec v1.6.1
    Checking allocator-api2 v0.2.9
   Compiling fixedbitset v0.4.0
   Compiling heck v0.4.0
   Compiling itertools v0.10.0
    Checking lock_api v0.4.10
    Checking instant v0.1.0
    Checking segvec v0.1.0
    Checking sync-unsafe-cell v0.1.0
   Compiling ascent_base v0.5.0 (<SNIP>/ascent_base)
    Checking crossbeam-channel v0.5.0
   Compiling petgraph v0.6.0
    Checking crossbeam-deque v0.8.1
    Checking num_cpus v1.2.0
    Checking parking_lot_core v0.9.8
    Checking rayon-core v1.11.0
   Compiling quote v1.0.26
    Checking rayon v1.7.0
   Compiling proc-macro-error-attr v1.0.4
    Checking hashbrown v0.14.0
    Checking dashmap v5.5.0
   Compiling proc-macro-error v1.0.4
   Compiling derive-syn-parse v0.1.5
   Compiling duplicate v0.4.0
error[E0599]: no method named `get_ident` found for struct `syn::Path` in the current scope
   --> ~/.cargo/registry/src/index.crates.io-6f17d22bba15001f/derive-syn-parse-0.1.5/src/fields.rs:192:26
    |
192 |     let name = attr.path.get_ident()?.to_string();
    |                          ^^^^^^^^^ help: there is a method with a similar name: `is_ident`

error[E0599]: no method named `get_ident` found for struct `syn::Path` in the current scope
   --> ~/.cargo/registry/src/index.crates.io-6f17d22bba15001f/derive-syn-parse-0.1.5/src/variants.rs:154:26
    |
154 |     let name = attr.path.get_ident()?.to_string();
    |                          ^^^^^^^^^ help: there is a method with a similar name: `is_ident`

For more information about this error, try `rustc --explain E0599`.
error: could not compile `derive-syn-parse` (lib) due to 2 previous errors
warning: build failed, waiting for other jobs to finish...
error: process didn't exit successfully: `~/.rustup/toolchains/stable-x86_64-apple-darwin/bin/cargo check --all-features --manifest-path ascent/Cargo.toml` (exit status: 101)
info: restoring <SNIP>/ascent/Cargo.toml
info: restoring <SNIP>/ascent_base/Cargo.toml
info: restoring <SNIP>/ascent_macro/Cargo.toml
error: process didn't exit successfully: `~/.rustup/toolchains/stable-x86_64-apple-darwin/bin/cargo hack check --workspace --all-features` (exit status: 1)

Bumping syn and itertools from …

[dependencies]
syn = { version = "1.0", features = [
    "derive",
    "full",
    "extra-traits",
    "visit-mut",
] }
itertools = "0.10"
# ...

… to …

[dependencies]
syn = { version = "1.0.109", features = [
    "derive",
    "full",
    "extra-traits",
    "visit-mut",
] }
itertools = "0.12"
# ...

fixes it.

Full terminal log
$ cargo minimal-versions check --workspace --all-features --ignore-private -v                                                      (base) 
info: modifying from <SNIP>/ascent/ascent/Cargo.toml
info: modifying from <SNIP>/ascent/ascent_base/Cargo.toml
info: modifying from <SNIP>/ascent/ascent_macro/Cargo.toml
info: running `rustup run nightly cargo update -Z minimal-versions`
warning: virtual workspace defaulting to `resolver = "1"` despite one or more workspace members being on edition 2021 which implies `resolver = "2"`
note: to keep the current resolver, specify `workspace.resolver = "1"` in the workspace root's manifest
note: to use the edition 2021 resolver, specify `workspace.resolver = "2"` in the workspace root's manifest
note: for more details see https://doc.rust-lang.org/cargo/reference/resolver.html#resolver-versions
    Updating crates.io index
info: running `~/.rustup/toolchains/stable-x86_64-apple-darwin/bin/cargo hack check --workspace --all-features`
info: running `cargo check --all-features` on ascent (1/3)
warning: virtual workspace defaulting to `resolver = "1"` despite one or more workspace members being on edition 2021 which implies `resolver = "2"`
note: to keep the current resolver, specify `workspace.resolver = "1"` in the workspace root's manifest
note: to use the edition 2021 resolver, specify `workspace.resolver = "2"` in the workspace root's manifest
note: for more details see https://doc.rust-lang.org/cargo/reference/resolver.html#resolver-versions
    Blocking waiting for file lock on package cache
    Blocking waiting for file lock on package cache
    Blocking waiting for file lock on package cache
    Finished dev [unoptimized + debuginfo] target(s) in 0.68s

info: running `cargo check --all-features` on ascent_base (2/3)
warning: virtual workspace defaulting to `resolver = "1"` despite one or more workspace members being on edition 2021 which implies `resolver = "2"`
note: to keep the current resolver, specify `workspace.resolver = "1"` in the workspace root's manifest
note: to use the edition 2021 resolver, specify `workspace.resolver = "2"` in the workspace root's manifest
note: for more details see https://doc.rust-lang.org/cargo/reference/resolver.html#resolver-versions
    Finished dev [unoptimized + debuginfo] target(s) in 0.02s

info: running `cargo check --all-features` on ascent_macro (3/3)
warning: virtual workspace defaulting to `resolver = "1"` despite one or more workspace members being on edition 2021 which implies `resolver = "2"`
note: to keep the current resolver, specify `workspace.resolver = "1"` in the workspace root's manifest
note: to use the edition 2021 resolver, specify `workspace.resolver = "2"` in the workspace root's manifest
note: for more details see https://doc.rust-lang.org/cargo/reference/resolver.html#resolver-versions
    Finished dev [unoptimized + debuginfo] target(s) in 0.05s
info: restoring <SNIP>/ascent/ascent/Cargo.toml
info: restoring <SNIP>/ascent/ascent_base/Cargo.toml
info: restoring <SNIP>/ascent/ascent_macro/Cargo.toml

Non-final lattice results visible to downstream rules

In the following program, the relation stop2 is a copy of stop.
And then obstruct is derived from stop the same way as obstruct2 is from stop2.
Therefore one would expect that the two relations have the same output, but instead the following happens:

1: [(1, 0, 2)]
2: []

But stop(1,2) is not part of the final result, (even though it is implied by roll(1,6), block(2), because it undergoes lattice merge with stop(1,4) implied by roll(1,6), block(4).

Yet it appears stop(1,2) is still used in deriving obstruct, even though its value isn't final yet.

use ascent::ascent_run;

fn main() {
    let prog = ascent_run! {
        relation block(i64) = vec![(2,),(4,)];
        relation roll(usize,i64) = vec![(0,3),(1,6)];
        lattice stop(usize,i64);
        stop(id,x) <--roll(id,x_start), block(x), if x < x_start;
        relation stop2(usize,i64);
        stop2(id,x) <-- stop(id,x);
        relation obstruct(usize,usize,i64);
        obstruct(id,id1,x2) <-- stop(id,x2), stop(id1,x2), if id1 < id;
        relation obstruct2(usize,usize,i64);
        obstruct2(id,id1,x2) <-- stop2(id,x2), stop2(id1,x2), if id1 < id;
    };
    println!(
        "1: {:?}\n2: {:?}",
        prog.obstruct,
        prog.obstruct2,
    );
}

ascent_macro: Upgrade syn to >= v2

syn has undergone a major version bump. Since it's a slow package to compile, it'd be nice to have just one version of it in my dependency tree.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.