Skip to content

Commit 1ff0be1

Browse files
committed
Improvements
1 parent 9b93e64 commit 1ff0be1

File tree

6 files changed

+20
-27
lines changed

6 files changed

+20
-27
lines changed

README.md

Lines changed: 2 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -50,17 +50,9 @@ Notice that the method `divide` now requires the parameter `b` to be non-zero. I
5050

5151
To follow along with this tutorial, make sure you have the following prerequisites installed:
5252

53-
- Java 20+, the JDK for compiling and running Java programs
54-
- Maven 3.6+, for building and dependency management
5553
- Visual Studio Code, for editing the code and using the LiquidJava extension
5654
- [Java Extension Pack by Red Hat](vscode:extension/redhat.java), which provides Java support in VS Code
5755

58-
Then, build the project using Maven:
59-
60-
```bash
61-
mvn clean install
62-
```
63-
6456
Next, install the [LiquidJava VS Code extension](vscode:extension/AlcidesFonseca.liquid-java). This extension provides the LiquidJava typechecker with real-time error reporting and syntax highlighting for the refinements, which we will use throughout this tutorial.
6557

6658
**Important:** Currently, only one error is reported at a time, so an error might not be reported if another one is present! In each part of the tutorial, make sure to fix all errors before moving on to the next one.
@@ -101,7 +93,7 @@ With this alias, we can replace all occurrences of `@Refinement("_ >= 0")` with
10193

10294
Now, let's explore how to use **state refinements** to specify and verify properties about the state of an object. Open [ExampleStateRefinements.java](./src/main/java/com/tutorial/part2/ExampleStateRefinements.java). Here, we specify that this object can only be in two states: `a` or `b`. Then, in the constructor, we specify that the initial state is `a`, through the `@StateRefinement` annotation. This annotation allows us to specify in which state the object should be before the method is called (`from`), and in which state it will be after the method execution (`to`). In the constructor, since it's the first method to be called, we can only specify the `to` state.
10395

104-
This object has two methods, also called `a` and `b`. From the state refinements, we can see that the method `a` can only be called when the object is in state `a` transiting to state `b`. Similarly, the method `b` can only be called when the object is in state `b`, transiting to state `a`. This means that we cannot call the same method twice in a row, since it would violate the protocol established by the state refinements. Try uncommenting line 22 to observe the error.
96+
This object has two methods, `toB` and `toA`. From the state refinements, we can see that the method `toB` can only be called when the object is in state `a` transiting to state `b`. Similarly, the method `toA` can only be called when the object is in state `b`, transiting to state `a`. This means that we cannot call the same method twice in a row, since it would violate the protocol established by the state refinements. Try uncommenting line 22 to observe the error.
10597

10698
#### Exercise
10799

@@ -116,7 +108,7 @@ Now, open [ExampleSocketUsage.java](./src/main/java/com/tutorial/part3/ExampleSo
116108

117109
#### Exercise
118110

119-
Now, let's refine another external class. Open [MathRefinements.java](./src/main/java/com/tutorial/part3/exercise/MathRefinements.java). Your task is to replace the `"true"` refinements with the appropriate ones to refine the `java.lang.Math` class. We want to ensure that the `abs` method returns a non-negative value, the `max` method returns the larger of the two arguments, and the `min` method returns the smaller one. To check your implementation, uncomment the code in [MathRefinementsTest.java](./src/main/java/com/tutorial/part3/exercise/MathRefinementsTest.java), which should have no errors after you complete the refinements.
111+
Now, let's refine another external class. Open [MathRefinements.java](./src/main/java/com/tutorial/part3/exercise/MathRefinements.java). Your task is to replace the `"true"` refinements with the appropriate ones to refine the `java.lang.Math` class. We want to ensure that the `max` method returns the larger of the two arguments and the `min` method returns the smaller one. To check your implementation, uncomment the code in [MathRefinementsTest.java](./src/main/java/com/tutorial/part3/exercise/MathRefinementsTest.java), which should have no errors after you complete the refinements.
120112

121113
### 4. Ghost Variables
122114

src/main/java/com/tutorial/part2/ExampleStateRefinements.java

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,15 +10,15 @@ public class ExampleStateRefinements {
1010
public ExampleStateRefinements() {}
1111

1212
@StateRefinement(from="a(this)", to="b(this)")
13-
public void a() {}
13+
public void toB() {}
1414

1515
@StateRefinement(from="b(this)", to="a(this)")
16-
public void b() {}
16+
public void toA() {}
1717

1818
public static void main(String[] args) {
1919
ExampleStateRefinements example = new ExampleStateRefinements();
20-
example.a();
21-
example.b();
22-
// example.b(); // uncomment for error
20+
example.toB();
21+
example.toA();
22+
// example.toA(); // uncomment for error
2323
}
2424
}

src/main/java/com/tutorial/part3/exercise/MathRefinements.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ public interface MathRefinements {
1212
@Refinement("_ == 2.7182818284590452354")
1313
public double E = 0;
1414

15-
@Refinement("true")
15+
@Refinement("arg0 >= 0 ? _ == arg0 : _ == -arg0")
1616
public int abs(int arg0);
1717

1818
@Refinement("true")

src/main/java/com/tutorial/part3/exercise/MathRefinementsTest.java

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -11,16 +11,16 @@ public static void test() {
1111
int a = 2;
1212
int b = -3;
1313

14+
@Refinement("_ == 3.141592653589793")
15+
double pi = Math.PI;
16+
17+
@Refinement("_ == 2.718281828459045")
18+
double e = Math.E;
19+
20+
@Refinement("_ == 3")
21+
int abs = Math.abs(b);
22+
1423
// // uncomment the lines below after completing MathRefinements.java
15-
// @Refinement("_ == 3.141592653589793")
16-
// double pi = Math.PI;
17-
18-
// @Refinement("_ == 2.718281828459045")
19-
// double e = Math.E;
20-
21-
// @Refinement("_ == 3")
22-
// int abs = Math.abs(b);
23-
2424
// @Refinement("_ == 2")
2525
// int max = Math.max(a, b);
2626

src/main/java/com/tutorial/part4/ArrayListRefinements.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,8 @@ public interface ArrayListRefinements<E> {
1111

1212
@StateRefinement(to="size(this) == 0")
1313
public void ArrayList();
14-
15-
@StateRefinement(to="size(this) == (size(old(this)) + 1)")
14+
15+
@StateRefinement(to="size(this) == size(old(this)) + 1")
1616
public boolean add(E elem);
1717

1818
public E get(@Refinement("0 <= _ && _ < size(this)") int index);

src/main/java/com/tutorial/part4/exercise/StackRefinements.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
@Ghost("int count")
99
public interface StackRefinements<E> {
1010

11+
// constructor initializes count to 0 by default
1112
public void Stack();
1213

1314
@StateRefinement(to="true")

0 commit comments

Comments
 (0)