ptal / pcp

Constraint programming in Rust

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Annotation of PCP variables

ptal opened this issue · comments

Our goal is to embed PCP inside Rust so we can use most of the Rust capabilities for describing our problem. However it poses some problems in case we want to use Rust code inside the #() or #{} anonymous macro. Inside these expression and block, we have no access to the type of the variable manipulated. So, for example, in #(x + (v + 1)), v+1 can be interpreted as plain Rust code or as a view for the variable Addition::new(v, 1).

It is really complicated to have the type of v at this stage of compilation, even if that would be the best and cleanest solution to decide how to compile the expression.

An alternative solution is to annotate in some way the PCP variables, so we can recognize a PCP expression from a Rust expression. It is a really basic "meta-type system" to disambiguate between both typing systems. For the moment we have:

    pcp! {
      let mut variables: VStore = VStore::new();
      let mut constraints: CStore = CStore::new();
      let n = 10usize;
      let mut queens = vec![];
      for _ in 0..n {
        let n: i32 = n as i32;
        queens.push(#(variables <- 0..n));
      }
      for i in 0..n-1 {
        for j in i + 1..n {
          let queen_i = queens[i];
          let queen_j = queens[j];
          let i = i as i32;
          let j = j as i32;
          let mi = -i;
          let mj = -j;
          #{
            constraints <- queen_i + i != queen_j + j;
            constraints <- queen_i + mi != queen_j + mj;
          }
        }
      }
      #{constraints <- Distinct(queens);}
    }

And we could probably obtain:

    pcp! {
      let mut variables: VStore = VStore::new();
      let mut constraints: CStore = CStore::new();
      let n = 10usize;
      let mut #queens = vec![];
      for _ in 0..n {
        let n: i32 = n as i32;
        queens.push(#(variables <- 0..n));
      }
      for i in 0..n-1 {
        for j in i + 1..n {
          let queen_i = queens[i];
          let queen_j = queens[j];
          let i = i as i32;
          let j = j as i32;
          #{
            constraints <- queen_i + i != queen_j + j;
            constraints <- queen_i - i != queen_j - j;
          }
        }
      }
      #{constraints <- Distinct(queens);}
    }

Note the declaration let mut #queens = ..., the compilation of queen_i - i becomes unambigous because we did not annotated i as being a "constraint world" variable.

The approach for the language is now different. See bonsai.