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

For and While Loops #88

Merged
merged 17 commits into from
Sep 24, 2024
Merged

For and While Loops #88

merged 17 commits into from
Sep 24, 2024

Conversation

ACassimiro
Copy link
Collaborator

Introducing functional loops to our rust lite semantics.

@ACassimiro ACassimiro marked this pull request as draft September 20, 2024 17:46
@ACassimiro ACassimiro marked this pull request as ready for review September 20, 2024 17:55
@@ -9,7 +9,7 @@ module RUST-CONDITIONAL-EXPRESSIONS

rule (if ptrValue(_, true) A:BlockExpression else _:IfElseExpression):ExpressionWithBlock => A
rule (if ptrValue(_, false) _:BlockExpression else B:IfElseExpression):ExpressionWithBlock => B

Copy link
Member

Choose a reason for hiding this comment

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

Remove spaces?

if (Patt :: .PathExprSegments):PathExprSegments < Last { .InnerAttributes B; (for2 Patt:Identifier:PatternNoTopAlt | .PatternNoTopAlts in First..Last B):IteratorLoopExpression; .NonEmptyStatements};

rule for2 Patt:Identifier:PatternNoTopAlt | .PatternNoTopAlts in _..Last B:BlockExpression =>
let Patt = (Patt :: .PathExprSegments):PathExprSegments + ptrValue(null, u64(Int2MInt(1:Int)));
Copy link
Member

Choose a reason for hiding this comment

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

Hmmm... This is interesting...

Right now, we have defined addition only between ints of the same kind, and I think that Rust does not allow adding ints of different types, e.g. 12u64 + 1u32 does not compile. Now, this probably works for our examples, but it's not correct, so here are some suggestions:

  • Add a TODO saying that this is wrong and it should be fixed.
  • define and use a function intOfSameType(1, Last) (Last should be a value when this rule is being applied, so it should have a concrete int type)

Copy link
Member

@virgil-serbanuta virgil-serbanuta left a comment

Choose a reason for hiding this comment

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

Looks good, but I left some suggestions for improvements.

| Bool
| String


syntax Range ::= intRange(PtrValue, PtrValue)
Copy link
Member

Choose a reason for hiding this comment

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

I think that this should be intRange(Value, Value), the pointer part does not help here.

@@ -769,7 +771,7 @@ https://doc.rust-lang.org/reference/items/extern-crates.html

```k

syntax RangePattern ::= "TODO: not needed yet, not implementing"
syntax RangePattern ::= Expression ".." Expression // "TODO: not needed yet, not implementing"
Copy link
Member

Choose a reason for hiding this comment

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

Remove the TODO since you just added this to the syntax.

@@ -101,6 +105,15 @@ module RUST-REPRESENTATION

syntax CallParamsList ::= reverse(CallParamsList, CallParamsList) [function, total]

syntax Bool ::= checkIntOfSameType(Expression, Expression) [function]
Copy link
Member

Choose a reason for hiding this comment

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

My previous suggestion was something a bit different, but, if you want to implement it this way, I think this should be something like:

syntax Bool ::= checkIntOfType(Value, Type)  [function, total]
rule checkIntOfType(u32(_), u32) => true
...

(you may need to import RUST-REPRESENTATION)

Then you would use it like this:

syntax LetStatement ::= incrementPatt(Identifier, Value)

rule incrementPatt(Patt:Identifier, ComparisonValue:Value) => 
            let Patt = (Patt :: .PathExprSegments):PathExprSegments + ptrValue(null, i32(Int2MInt(1:Int)));
        requires checkIntOfType(ComparisonValue, i32)
...

and like this:

    rule for Patt:Identifier:PatternNoTopAlt | R:PatternNoTopAlts in ptrValue(_, intRange(First, Last)) #as Range B:BlockExpression => 
            {
                .InnerAttributes
                let Patt = First;
                (for1 Patt:Identifier:PatternNoTopAlt | R:PatternNoTopAlts in Range B:BlockExpression):IteratorLoopExpression; 
                .NonEmptyStatements
            };
        requires checkIntOfSameType(First, Last)
    rule for1 Patt:Identifier:PatternNoTopAlt | .PatternNoTopAlts in ptrValue(_, intRange(_First, Last)) #as Range B:BlockExpression => 
                if (Patt :: .PathExprSegments):PathExprSegments < Last { .InnerAttributes B; (for2 Patt:Identifier:PatternNoTopAlt | .PatternNoTopAlts in Range B):IteratorLoopExpression;  .NonEmptyStatements};
            
    rule for2 Patt:Identifier:PatternNoTopAlt | .PatternNoTopAlts in ptrValue(_, intRange(_First, ptrValue(_, Last))) B:BlockExpression => 
            incrementPatt(Patt, Last)
            ~> for1 Patt:Identifier:PatternNoTopAlt | .PatternNoTopAlts in Range B

Note that:

  1. This removes the need for using ptrValue(...) in a lot of places
  2. Changing the start of the range was not needed since it was not actually used in for1 or for2

Because of 2, this means that you can probably write simpler code:

    syntax IteratorLoopExpression ::=  "for1" Pattern "limit" PtrValue BlockExpression
                                    | "for2" Pattern "limit" PtrValue BlockExpression

    rule for Patt:Identifier:PatternNoTopAlt | R:PatternNoTopAlts in ptrValue(_, intRange(First, Last)) => 
            {
                .InnerAttributes
                let Patt = First;
                (for1 Patt:Identifier:PatternNoTopAlt | R:PatternNoTopAlts limit Last B:BlockExpression):IteratorLoopExpression; 
                .NonEmptyStatements
            };
        requires checkIntOfSameType(First, Last)
    rule for1 Patt:Identifier:PatternNoTopAlt | .PatternNoTopAlts limit Last B:BlockExpression => 
                if (Patt :: .PathExprSegments):PathExprSegments < Last { .InnerAttributes B; (for2 Patt:Identifier:PatternNoTopAlt | .PatternNoTopAlts limit Last B):IteratorLoopExpression;  .NonEmptyStatements};
            
    rule for2 Patt:Identifier:PatternNoTopAlt | .PatternNoTopAlts limit ptrValue(_, LastValue) #as Last B:BlockExpression => 
            incrementPatt(Patt, LastValue)
            ~> for1 Patt:Identifier:PatternNoTopAlt | .PatternNoTopAlts limit Last B

requires checkIntOfSameType(First, Last)

rule for1 Patt:Identifier:PatternNoTopAlt | .PatternNoTopAlts limit Last B:BlockExpression =>
if (Patt :: .PathExprSegments):PathExprSegments < Last { .InnerAttributes B; (for2 Patt:Identifier:PatternNoTopAlt | .PatternNoTopAlts limit Last B):IteratorLoopExpression; .NonEmptyStatements};
Copy link
Member

Choose a reason for hiding this comment

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

I would split this into multiple lines.

Also, you can probably inline the "for2" rule below if you want.

@ACassimiro ACassimiro merged commit 69aa4f7 into main Sep 24, 2024
1 check passed
@ACassimiro ACassimiro deleted the for-loops branch September 24, 2024 16:25
@ACassimiro
Copy link
Collaborator Author

Addresses #18.

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.

2 participants