Skip to content

Commit ec746eb

Browse files
committed
Improve Diagnostic Structure Section
1 parent 4f6d545 commit ec746eb

1 file changed

Lines changed: 14 additions & 14 deletions

File tree

diagnostics/diagnostic-structure.md

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -16,34 +16,34 @@ Each part gives a different piece of information:
1616
| Part | Meaning |
1717
| --- | --- |
1818
| `Refinement Error` | The kind of diagnostic being reported |
19-
| `#ret² == x / 2 && x > 0` | What LiquidJava knows at the return site. Here, the returned value is `x / 2`, and the parameter refinement says `x > 0` |
20-
| `is not a subtype of` | LiquidJava is checking whether the inferred refinement is strong enough to satisfy the declared one |
21-
| `#ret² > 0` | The declared return refinement, obtained from `@Refinement(value="_ > 0", ...)`. |
22-
| Source snippet | The surrounding lines help locate the failing code in context |
23-
| Caret line | The `^` marks the exact expression that caused the violation |
24-
| `result must be positive` | The custom error message from the annotation's `msg` parameter |
25-
| `Counterexample: x == 1 && #ret² == 0` | A concrete model showing why the check fails. Here we can see the failure arises because if `x == 1`, then `x / 2 == 0` |
19+
| `#ret² == x / 2 && x > 0` | The inferred refinement, which indicates that the return value is `x / 2`, and the `x` parameter is `x > 0` |
20+
| `is not a subtype of` | LiquidJava is checking whether the inferred refinement is strong enough to satisfy the expected one |
21+
| `#ret² > 0` | The expected refinement, which specifies that the return value must be positive |
22+
| Source snippet | The surrounding lines that help locate the failing code in context |
23+
| Caret line | The line with the `^` indicating the exact expression that caused the error |
24+
| `result must be positive` | The custom error message obtained from the annotation's `msg` parameter |
25+
| `Counterexample: x == 1 && #ret² == 0` | A concrete model showing why the typechecking failed |
2626

2727
The error message also includes the absolute path of the file and line where the error was reported, which can be clicked to jump the source code location in the editor.
2828

29-
## Understanding the Counterexample
29+
## Understanding the Error
3030

31-
The counterexample is a concrete assignment of values that makes the verification fail.
31+
Refinement errors may provide a counterexample, which is a concrete assignment of values that makes the verification fail.
3232

3333
In the example above:
3434
- `x == 1` satisfies the parameter refinement `x > 0`
3535
- `#ret² == 0` follows from the return expression `x / 2`, since integer division makes `1 / 2 == 0`
3636
- `0 > 0` is false, so the declared return refinement is violated
3737

38-
So the counterexample explains exactly why LiquidJava cannot prove that `x / 2` is always positive even when `x > 0`. To fix this error, we would need to either change the return expression to allow to return zero with the refinement `_ >= 0`, or strengthen the parameter refinement to require `x > 1`.
38+
So the counterexample explains exactly why LiquidJava cannot prove that `x / 2` is always positive even when `x > 0`. To fix this error, we would need to either weaken the return expression to allow to return zero with the refinement `_ >= 0`, or strengthen the parameter refinement to require `x > 1`.
3939

40-
## Understanding Internal Variables
40+
## Internal Variables
4141

42-
Names such as `#ret²` are internal variables introduced by LiquidJava during verification. The small superscript number is a counter used to keep those generated variables unique.
42+
Names such as `#ret²` are internal variables created by LiquidJava during verification. The small superscript number is a counter used to keep those generated variables unique.
4343

44-
LiquidJava converts expressions into an internal A-normal form (ANF) before verification. Every time it creates a fresh internal variable during that process, the counter is incremented. This is why you may see names such as `#ret²` in the diagnostics.
44+
LiquidJava converts expressions into an internal A-normal form (ANF) before verification. Every time it creates a fresh internal variable during that process, the counter is incremented. This is why you may see names such as `#ret²` in the diagnostics. In practice, you can read `#ret²` as "the internal variable that represents this return value occurrence".
4545

46-
In practice, you can read `#ret²` as "the internal variable that represents this return value occurrence".
46+
The following example shows how the internal variables are created during the typechecking:
4747

4848
```java
4949
int example(int x) { // x⁰

0 commit comments

Comments
 (0)