Skip to content

Start conversion to easy-smt#45

Merged
avanhatt merged 66 commits intoverify-mainfrom
easy-smt
Jan 31, 2023
Merged

Start conversion to easy-smt#45
avanhatt merged 66 commits intoverify-mainfrom
easy-smt

Conversation

@sampsyo
Copy link
Collaborator

@sampsyo sampsyo commented Jan 21, 2023

As discussed on Slack, here's a first attempt to move from rsmt2 to easy-smt. Here are the high-level takeaways:

  • The actual interaction with the solver was easy to move over. No problem! Just had to fiddle around with the APIs to line them up.
  • The real work here is the drudgery of changing from plain ol' strings for the SMT expressions to the library's SExpr type.

I got everything in solver.rs converted, including all the SMT generation and the interaction with the solver. This took me about 3 hours to move everything over—almost all of that was replacing calls to format! with explicit S-expression construction calls. It's not exactly fun, but it's not exactly hard either.

There is more drudgery ahead: the files in encoded_ops have a lot of raw SMT strings in them and will be a lot of work to convert.

There is a chance I have made a terrible mistake and I should not have tried to do all this annoying conversion at all: instead, we could try to parse the strings we're already generating and turn them into SExprs. Or we could attempt to hack easy-smt to allow us to shove strings directly into the solver, which it doesn't currently allow (you have to provide an SExpr). Both of those seem very reasonable in retrospect, but now I wonder if either of them would be simpler than just forging ahead and finishing the conversion. I'd be interested in others' opinions, given what the code looks like in solver.rs after the conversion.

I tried to do this as fast as I could, not trying to clean anything up
after the transition, and just get the replacement done as quickly as
possible. (And it still took me about 3 hours.) The main work, of
course, is replacing all the raw string manipulation (mainly `format!`
calls) with S-expression builder calls.
There is a lot of typing to be done here!
}

let assumption_str = format!("(and {})", assumptions.join(" "));
let assumption_conjunction = solver.and_many(assumptions);
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nice

I'm trying to get to a place where the crate compiles, even though the
encoded ops don't work at all.
@sampsyo
Copy link
Collaborator Author

sampsyo commented Jan 24, 2023

As we discussed synchronously today, I've mucked things up so that our crate builds. That meant temporarily:

  • removing the files under encoded_ops
  • replacing the calls into their SMT-generating functions with todo!()

It works! I haven't tried running any tests, because I don't feel qualified to know which tests should be runnable in this semi-broken state. (I could probably figure that out, but I'm going to move on to trying to rewrite the encoded ops stuff instead of spending time on that.)

Now using the builder to construct contexts. And there's a cool new
`numeral` helper for building number literals of all kinds!
}

pub fn vir_to_rsmt2_constant_ty(&self, ty: &Type) -> String {
pub fn vir_to_rsmt2_constant_ty(&self, ty: &Type) -> SExpr {
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: remove rsmt2 from name

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks; addressed!

@avanhatt
Copy link
Owner

Other important TODO before this becomes the default: easy-smt's debugging doesn't list the actual values. We should make sure things like this get displayed in a more useful way:

Assertion list is feasible
LHS and RHS equality condition:
        SExpr::List(14853)            // <- this should have named values

@avanhatt
Copy link
Owner

^ Doing a pass to add ctx.smt.display(...) calls.

@avanhatt
Copy link
Owner

Currently failing tests:

failures:
2363
test_broken_uextend
2364
test_clz
2365
test_ctz
2366
test_ctz_broken
2367
test_sextend
2368
test_uextend

}
Type::Int => i.to_string(),
Type::Int => self.smt.numeral(i),
Type::Bool => {
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Aha, I think this is causing the failing tests! Will fix.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh Lordy, that is obviously wrong!! Nice catch!

@avanhatt
Copy link
Owner

Ok, I think the clz and ctz encodings might actually be broken. Investigating!


(assert (= y1_{id} (bvlshr x2_{id} #x0001)))
(assert (ite (not (= y1_{id} (_ bv0 16))) (= ret5_{id} ret4_{id}) (= ret5_{id} (bvadd ret4_{id} (_ bv1 16)))))
(assert (ite (not (= y1_{id} (_ bv0 16))) (= x1_{id} y1_{id}) (= x1_{id} x2_{id})))
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

after this line, try adding

; last round
(declare-fun ret6_{id} () (_ BitVec 16))
(assert (ite (not (= x1_{id} (_ bv0 16))) (= ret6_{id} ret5_{id}) (= ret6_{id} (bvadd ret5_{id} (_ bv1 16)))))

and then regenerating?

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Aha, good catch! Trying this now


(assert (= y1_{id} (bvlshr x2_{id} #x00000001)))
(assert (ite (not (= y1_{id} (_ bv0 32))) (= ret5_{id} ret4_{id}) (= ret5_{id} (bvadd ret4_{id} (_ bv1 32)))))
(assert (ite (not (= y1_{id} (_ bv0 32))) (= x1_{id} y1_{id}) (= x1_{id} x2_{id})))
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

after this line try adding:

; last round
(declare-fun ret6_{id} () (_ BitVec 32))
(assert (ite (not (= x1_{id} (_ bv0 32))) (= ret6_{id} ret5_{id}) (= ret6_{id} (bvadd ret5_{id} (_ bv1 32)))))

and then regenerating?


(assert (= y1_{id} (bvlshr x2_{id} #x0000000000000001)))
(assert (ite (not (= y1_{id} (_ bv0 64))) (= ret6_{id} ret5_{id}) (= ret6_{id} (bvadd ret5_{id} (_ bv1 64)))))
(assert (ite (not (= y1_{id} (_ bv0 64))) (= x1_{id} y1_{id}) (= x1_{id} x2_{id})))
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

after this line try adding

; last round
(declare-fun ret7_{id} () (_ BitVec 64))
(assert (ite (not (= x1_{id} (_ bv0 64))) (= ret7_{id} ret6_{id}) (= ret7_{id} (bvadd ret6_{id} (_ bv1 64)))))

and then regenerating?

@avanhatt avanhatt marked this pull request as ready for review January 31, 2023 15:26
@avanhatt avanhatt merged commit 61c88f5 into verify-main Jan 31, 2023
avanhatt pushed a commit that referenced this pull request May 26, 2023
* implement `wasi-filesystem::readdir` and related functions

This adds a `directory_list` test and provides the required host implementation.

I've also added a file length check to the `file_read` test, just to cover a bit
more of the API.

Signed-off-by: Joel Dice <joel.dice@fermyon.com>

* fix memory corruption in `fd_readdir` polyfill

We were copying `name.len() * 256` bytes instead of just `name.len()` bytes,
which was overwriting other parts of `State` and causing untold havoc.

Signed-off-by: Joel Dice <joel.dice@fermyon.com>

* check type of entry in `Table::delete`

Signed-off-by: Joel Dice <joel.dice@fermyon.com>

Signed-off-by: Joel Dice <joel.dice@fermyon.com>
avanhatt pushed a commit that referenced this pull request May 26, 2023
* implement `wasi-filesystem::readdir` and related functions

This adds a `directory_list` test and provides the required host implementation.

I've also added a file length check to the `file_read` test, just to cover a bit
more of the API.

Signed-off-by: Joel Dice <joel.dice@fermyon.com>

* fix memory corruption in `fd_readdir` polyfill

We were copying `name.len() * 256` bytes instead of just `name.len()` bytes,
which was overwriting other parts of `State` and causing untold havoc.

Signed-off-by: Joel Dice <joel.dice@fermyon.com>

* check type of entry in `Table::delete`

Signed-off-by: Joel Dice <joel.dice@fermyon.com>

Signed-off-by: Joel Dice <joel.dice@fermyon.com>
avanhatt pushed a commit to wellesley-prog-sys/wasmtime that referenced this pull request Oct 18, 2024
Add support for fetching models containing unspecified values.

With the addition of declared sorts in bytecodealliance#141, this broke the code that
parses constants from SMT models. The backend solvers differ on how they
implement this. This PR deals with the CVC5 format only, in which
unspecified values are represented as something like `(as @Unspecified_0
Unspecified)`.

Updates avanhatt#45
avanhatt pushed a commit to wellesley-prog-sys/wasmtime that referenced this pull request Oct 23, 2024
Since the addition of enum type instantiations bytecodealliance#167 the counter-example
printing is bloated with a lot of enum variants. These convey little
information if they are constants (unit enums). This PR skips them in
printing.

Updates avanhatt#45
avanhatt pushed a commit to wellesley-prog-sys/wasmtime that referenced this pull request Oct 23, 2024
Since the addition of enum type instantiations bytecodealliance#167 the counter-example
printing is bloated with a lot of enum variants. These convey little
information if they are constants (unit enums). This PR skips them in
printing.

Updates avanhatt#45
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

Successfully merging this pull request may close these issues.

3 participants