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

Predicates for tuple.n #96

Open
noriapi opened this issue Feb 27, 2021 · 2 comments
Open

Predicates for tuple.n #96

noriapi opened this issue Feb 27, 2021 · 2 comments

Comments

@noriapi
Copy link

noriapi commented Feb 27, 2021

Something like this.

use predicates::reflection;
use predicates::Predicate;
use std::fmt;

#[derive(Debug, Clone, Copy, PartialEq, Eq)]
struct Tuple0<T>(T);

fn tuple0<T>(inner: T) -> Tuple0<T> {
    Tuple0(inner)
}

impl<T: fmt::Display> fmt::Display for Tuple0<T> {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        write!(f, "{{let var = var.0; {}}}", self.0)
    }
}

impl<T: fmt::Display> reflection::PredicateReflection for Tuple0<T> {}

impl<T0, U0> Predicate<(U0,)> for Tuple0<T0>
where
    T0: fmt::Display + Predicate<U0>,
{
    fn eval(&self, variable: &(U0,)) -> bool {
        self.0.eval(&variable.0)
    }
}

impl<T, U, U1> Predicate<(U, U1)> for Tuple0<T>
where
    T: fmt::Display + Predicate<U>,
{
    fn eval(&self, variable: &(U, U1)) -> bool {
        self.0.eval(&variable.0)
    }
}

// impl<T, U, U1, U2> Predicate<(U, U1, U2)> for Tuple0<T>
// impl<T, U, U1, U2, U3> Predicate<(U, U1, U2, U3)> for Tuple0<T>
// ...

#[derive(Debug, Clone, Copy, PartialEq, Eq)]
struct Tuple1<T>(T);

fn tuple1<T>(inner: T) -> Tuple1<T> {
    Tuple1(inner)
}

impl<T: fmt::Display> fmt::Display for Tuple1<T> {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        write!(f, "{{let var = var.1; {}}}", self.0)
    }
}

impl<T: fmt::Display> reflection::PredicateReflection for Tuple1<T> {}

impl<T, U0, U> Predicate<(U0, U)> for Tuple1<T>
where
    T: fmt::Display + Predicate<U>,
{
    fn eval(&self, variable: &(U0, U)) -> bool {
        self.0.eval(&variable.1)
    }
}

// impl<T, U0, U, U2> Predicate<(U0, U, U2)> for Tuple1<T>
// impl<T, U0, U, U2, U3> Predicate<(U0, U, U2, U3)> for Tuple1<T>
// ...

fn main() {
    use predicates::prelude::*;

    let t1 = (0,);
    let t2 = (0, 1);

    let p0 = tuple0(predicates::ord::eq(0));
    let p1 = tuple1(predicates::ord::eq(2));

    assert_eq!(p0.eval(&t1), true);
    assert_eq!(p0.eval(&t2), true);
    assert_eq!(p1.eval(&t2), false);
    assert_eq!(p0.and(p1).eval(&t2), false);
    assert_eq!(p0.or(p1).eval(&t2), true);
}
@epage
Copy link
Contributor

epage commented Mar 1, 2021

Wish we could use const-generics for indexing into a tuple.

The main question I can think of is how many tuple positions should we support?

@noriapi
Copy link
Author

noriapi commented Mar 1, 2021

Wish we could use const-generics for indexing into a tuple.

Yes, I agree.

The main question I can think of is how many tuple positions should we support?

Std common traits (like Debug PartialEq Clone...) are only implemented on tuples of arity 12 or less.
So, I think 12 would be enough.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants