You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: diagnostics/diagnostic-structure.md
+14-14Lines changed: 14 additions & 14 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -16,34 +16,34 @@ Each part gives a different piece of information:
16
16
| Part | Meaning |
17
17
| --- | --- |
18
18
|`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|
26
26
27
27
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.
28
28
29
-
## Understanding the Counterexample
29
+
## Understanding the Error
30
30
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.
32
32
33
33
In the example above:
34
34
-`x == 1` satisfies the parameter refinement `x > 0`
35
35
-`#ret² == 0` follows from the return expression `x / 2`, since integer division makes `1 / 2 == 0`
36
36
-`0 > 0` is false, so the declared return refinement is violated
37
37
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`.
39
39
40
-
## Understanding Internal Variables
40
+
## Internal Variables
41
41
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.
43
43
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".
45
45
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:
0 commit comments