Skip to content

Read symbolic value at symbolic address #152

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

Draft
wants to merge 17 commits into
base: master
Choose a base branch
from
Draft

Conversation

Stevengre
Copy link
Contributor

No description provided.

@Stevengre Stevengre requested a review from tothtamas28 June 24, 2025 10:39
@Stevengre Stevengre self-assigned this Jun 24, 2025
Stevengre and others added 4 commits June 25, 2025 10:44
…ing a boolean wrapper for symbolic writes. This update includes detailed explanations of termination control, reordering for optimization, and write consolidation strategies. Adjusted comments for clarity and improved documentation.
@Stevengre Stevengre changed the base branch from jh/sym-write-mem to master July 3, 2025 05:19
@Stevengre Stevengre changed the base branch from master to jh/sym-write-mem July 3, 2025 05:20
Base automatically changed from jh/sym-write-mem to master July 9, 2025 08:02
Comment on lines +38 to +39
rule dropFront(DROP, #WB(FLAG, I, V, NUM, B:SparseBytes)) => #WB(FLAG, I -Int DROP, V, NUM, dropFront(DROP, B))
[simplification(45)]
Copy link
Contributor

Choose a reason for hiding this comment

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

Consider DROP > I. In that case, WriteBytes(I -Int DROP, ...) is .SparseBytes.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

WriteBytes and #WB have different behaviors. #WB currently doesn't handle index < 0.

I'll be adding a rule to #WB so that I < 0 acts as a no-op (only written bytes are kept).

Copy link
Contributor

Choose a reason for hiding this comment

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

That doesn't seem to be sufficient. Consider a case where I <Int DROP <Int I +Int NUM:

I = 0
NUM = 2
DROP = 1
V = 65535
B = b"=\x00\x00"  // I will treat SparseBytes as Bytes for simplicity
FLAG = true

LHS:
dropFront(DROP, #WB(FLAG, I, V, NUM, B)) =>
dropFront(1, #WB(true, 0, 65535, 2, b"\x00\x00")) =>
dropFront(1, b"\xff\xff") =>
b"\xff"

RHS:
#WB(FLAG, I -Int DROP, V, NUM, dropFront(DROP, B)) =>
#WB(true, 0 -Int 1, 65535, 2, dropFront(1, b"\x00\x00")) =>
#WB(true, -1, 65535, 2, b"x00")) =>
b"x00"

…erations and symbolic write blocks. Added a rule for 16-bit integer simplification and improved handling of pickFront and dropFront operations on symbolic write blocks. Updated test cases to reflect changes in symbolic index handling.

## Right Shift Operations

The `>>SparseBytes` operator performs a right shift operation on SparseBytes, effectively dropping the first N bytes from the sparse byte structure while maintaining the integer value semantics of the remaining bytes. Unlike `dropFront`, which simply removes N bytes from the beginning, `>>SparseBytes` performs a byte-level right shift that preserves the underlying integer representation of the data.
Copy link
Contributor

Choose a reason for hiding this comment

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

effectively dropping the first N bytes from the sparse byte structure while maintaining the integer value semantics of the remaining bytes

Can you give an example? E.g., using syntax somewhat freely, given a bytes value

0x01 0x02 0x03 0x04

dropFront 1 gives

0x02 0x03 0x04

What does >>SparseBytes 1 evaluate to? Is it

0x00 0x01 0x02 0x03

Copy link
Contributor Author

Choose a reason for hiding this comment

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

On concrete, dropFront and >>SparseBytes behave identically. The only difference arises during symbolic writes to the queue, specifically for #WB. This distinction is crucial for the pickFront rule, which handles cases like writing a small num followed by a large num (e.g., as seen in our test specs: 5 |->).

Copy link
Contributor

Choose a reason for hiding this comment

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

So this is an alias for dropFront used in simplification rules? I want to rule out the case that the symbolic and concrete semantics of >>SparseBytes differ.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes, you can understand >>Sparse as being specifically for handling a special case of #WB under pickFront that the previous dropFront simplification rule couldn't handle. And the dropFront simplification rule is indeed correct.

@Stevengre Stevengre requested a review from tothtamas28 July 10, 2025 10:13
Comment on lines +38 to +39
rule dropFront(DROP, #WB(FLAG, I, V, NUM, B:SparseBytes)) => #WB(FLAG, I -Int DROP, V, NUM, dropFront(DROP, B))
[simplification(45)]
Copy link
Contributor

Choose a reason for hiding this comment

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

That doesn't seem to be sufficient. Consider a case where I <Int DROP <Int I +Int NUM:

I = 0
NUM = 2
DROP = 1
V = 65535
B = b"=\x00\x00"  // I will treat SparseBytes as Bytes for simplicity
FLAG = true

LHS:
dropFront(DROP, #WB(FLAG, I, V, NUM, B)) =>
dropFront(1, #WB(true, 0, 65535, 2, b"\x00\x00")) =>
dropFront(1, b"\xff\xff") =>
b"\xff"

RHS:
#WB(FLAG, I -Int DROP, V, NUM, dropFront(DROP, B)) =>
#WB(true, 0 -Int 1, 65535, 2, dropFront(1, b"\x00\x00")) =>
#WB(true, -1, 65535, 2, b"x00")) =>
b"x00"

Comment on lines +64 to +65
rule #WB(FLAG, I, V, NUM, B:SparseBytes) >>SparseBytes SHIFT => #WB(FLAG, maxInt(0, I -Int SHIFT), V >>Int (SHIFT *Int 8), NUM, B >>SparseBytes SHIFT)
requires SHIFT >=Int 0 [simplification(45), preserves-definedness]
Copy link
Contributor

Choose a reason for hiding this comment

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

I think there is a similar counterexample here for the I <Int SHIFT <Int I +Int NUM case.

Copy link
Contributor

Choose a reason for hiding this comment

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

In fact, these two simplifications look analogous on the LHS but differ on the RHS:

LHS
dropFront(DROP, #WB(FLAG, I, V, NUM, B:SparseBytes))
vs
#WB(FLAG, I, V, NUM, B:SparseBytes) >>SparseBytes SHIFT

RHS
#WB(FLAG, I -Int DROP, V, NUM, dropFront(DROP, B))
vs
#WB(FLAG, maxInt(0, I -Int SHIFT), V >>Int (SHIFT *Int 8), NUM, B >>SparseBytes SHIFT)

If B >>SparseBytes X and dropFront(X, B) are the same, what's the reason for this discrepancy? If they are not, I still would like to see an example for >>SparseBytes applied on concrete values.

Copy link
Contributor Author

@Stevengre Stevengre Jul 11, 2025

Choose a reason for hiding this comment

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

  rule dropFront(DROP, #WB(FLAG, I, V, NUM, B:SparseBytes)) => #WB(FLAG, maxInt(0, I -Int SHIFT), V >>Int (SHIFT *Int 8), NUM -Int DROP, dropFront(DROP, B)) 
    [simplification(45)]

Found that the dropFront and >>SparseBytes should be the same, so why I provide >>SparseBytes is that the previous simp rule for dropFront is wrong.

Quick idea to fix this issue:

  1. provide a correct simp rule for dropFront
  2. delete the >>SparseBytes
  3. check if the #WB have the correct implementation when index <=0 && num <=0.
  4. Verifying the implementation's correctness using a decision tree with a truth table.

@tothtamas28 tothtamas28 requested a review from jberthold July 11, 2025 09:36
@Stevengre Stevengre marked this pull request as draft July 11, 2025 09:58
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