Skip to content

Commit db9eace

Browse files
improvements on the verification presentation
1 parent cf960f6 commit db9eace

11 files changed

Lines changed: 145 additions & 156 deletions

File tree

‎verification/Makefile‎

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -10,25 +10,25 @@ all: build prove
1010
build: clean
1111
kompile -d patterns/tree_string --no-prelude --backend java --main-module JS-VERIFIER --syntax-module JS-SYNTAX patterns/tree_string/js-verifier.k
1212
kompile -d patterns/tree_float --no-prelude --backend java --main-module JS-VERIFIER --syntax-module JS-SYNTAX patterns/tree_float/js-verifier.k
13-
kompile -d patterns/list --no-prelude --backend java --main-module JS-VERIFIER --syntax-module JS-SYNTAX patterns/list/js-verifier.k
13+
kompile -d patterns/list --no-prelude --backend java --main-module JS-VERIFIER --syntax-module JS-SYNTAX patterns/list/js-verifier.k
1414

1515
.PHONY: prove
1616
prove:
1717
@echo "List"
18-
krun -d patterns/list --smt none --prove list/reverse_spec.k list/reverse.js
18+
krun -d patterns/list --smt none --prove list/reverse_spec.k list/reverse.js
1919
krun -d patterns/list --smt none --prove list/append_spec.k list/append.js
2020
@echo "BST String"
21-
krun -d patterns/tree_string --smt_prelude $(K_Z3)/string.smt2 --prove bst/string_find_spec.k bst/find.js
22-
krun -d patterns/tree_string --smt_prelude $(K_Z3)/string.smt2 --prove bst/string_insert_spec.k bst/insert.js
23-
krun -d patterns/tree_string --smt_prelude $(K_Z3)/string.smt2 --prove bst/string_delete_spec.k bst/delete.js
21+
krun -d patterns/tree_string --smt_prelude $(K_Z3)/string.smt2 --prove bst/string_find_spec.k bst/find.js
22+
krun -d patterns/tree_string --smt_prelude $(K_Z3)/string.smt2 --prove bst/string_insert_spec.k bst/insert.js
23+
krun -d patterns/tree_string --smt_prelude $(K_Z3)/string.smt2 --prove bst/string_delete_spec.k bst/delete.js
2424
@echo "BST Float"
25-
krun -d patterns/tree_float --smt_prelude $(K_Z3)/float.smt2 --prove bst/float_find_spec.k bst/find.js
26-
krun -d patterns/tree_float --smt_prelude $(K_Z3)/float.smt2 --prove bst/float_insert_spec.k bst/insert.js
27-
krun -d patterns/tree_float --smt_prelude $(K_Z3)/float.smt2 --prove bst/float_delete_spec.k bst/delete.js
25+
krun -d patterns/tree_float --smt_prelude $(K_Z3)/string.smt2 --prove bst/float_find_spec.k bst/find.js
26+
krun -d patterns/tree_float --smt_prelude $(K_Z3)/string.smt2 --prove bst/float_insert_spec.k bst/insert.js
27+
krun -d patterns/tree_float --smt_prelude $(K_Z3)/string.smt2 --prove bst/float_delete_spec.k bst/delete.js
2828
@echo "AVL String"
29-
krun -d patterns/tree_string --smt_prelude $(K_Z3)/string.smt2 --prove avl/avl_find_spec.k avl/avl.js
30-
krun -d patterns/tree_string --smt_prelude $(K_Z3)/string.smt2 --prove avl/avl_insert_spec.k avl/avl.js
31-
krun -d patterns/tree_string --smt_prelude $(K_Z3)/string.smt2 --prove avl/avl_delete_spec.k avl/avl.js
29+
krun -d patterns/tree_string --smt_prelude $(K_Z3)/string.smt2 --prove avl/avl_find_spec.k avl/avl.js
30+
krun -d patterns/tree_string --smt_prelude $(K_Z3)/string.smt2 --prove avl/avl_insert_spec.k avl/avl.js
31+
krun -d patterns/tree_string --smt_prelude $(K_Z3)/string.smt2 --prove avl/avl_delete_spec.k avl/avl.js
3232

3333
.PHONY: clean
3434
clean:

‎verification/README.md‎

Lines changed: 26 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,21 @@
11
## JavaScript Program Verification
22

3-
You can verify a JavaScript program by using the semantics and the K verifier.
4-
5-
All you need to do is to write a specification and run `krun` with `--prove` option:
3+
The JavaScript program verifier combines the K verification infrastructure with the JavaScript semantics.
4+
The verification is enabled by the `--prove` option of the `krun` command:
65
```
76
$ krun --prove <specification.k> <program.js>
87
```
9-
The specification `<specification.k>` essentially describes a pre-/post-condition,
8+
The specification `<specification.k>` essentially describes a set of pre-/post-conditions,
109
and it should be given as a reachability rule written in K.
1110

12-
You can quickly run all of the verification examples using the [Makefile](Makefile):
11+
Use the [Makefile](Makefile) to quickly run all of the verification examples:
1312
```
1413
$ make
1514
```
16-
17-
We provide the verification results, [verification.out](verification.out).
18-
For each program, the verifier simply outputs the following triple when it succeeds in verifying the program:
19-
```
20-
true
21-
[]
22-
true
23-
```
24-
Note that the verifier will simply crash or not terminate when the program is not correct. We will improve usability of the verifier in the future.
15+
The output of the ```make``` command is available in [verification.out](verification.out).
16+
For each program, the verifier simply outputs ```true``` when it succeeds in verifying the program.
17+
Note that the verifier may crash or fail to terminate when the program is not correct.
18+
We will improve usability of the verifier in the future.
2519

2620

2721
### List of Programs and Specifications
@@ -40,7 +34,6 @@ We have the following example programs and specifications to be verified:
4034
| AVL delete | [avl/avl.js:delete](avl/avl.js#L120) | [avl/avl_delete_spec.k](avl/avl_delete_spec.k) |
4135

4236

43-
4437
### Specifications
4538

4639
The specifications are given as reachability rules using the K syntax and are
@@ -55,7 +48,7 @@ rule
5548
(.Bag => ?_:Bag)
5649
...</envs>
5750
<objs>...
58-
(string_htree(O1)(T1:StringTree) => string_htree(?O2)(?T2:StringTree))
51+
(htree(O1)(T1:StringTree) => htree(?O2)(?T2:StringTree))
5952
OBJS:Bag
6053
(.Bag => ?_:Bag)
6154
...</objs>
@@ -68,10 +61,10 @@ rule
6861
=>
6962
?O2:NullableObject
7063
...</k>
71-
requires string_avl(T1) andBool string_tree_height(T1) <Int (4294967296 -Int 1)
72-
ensures string_avl(?T2) andBool string_tree_keys(?T2) ==K { V } U string_tree_keys(T1)
73-
andBool string_tree_height(T1) <=Int string_tree_height(?T2)
74-
andBool string_tree_height(?T2) <=Int string_tree_height(T1) +Int 1
64+
requires avl(T1) andBool tree_height(T1) <Int (4294967296 -Int 1)
65+
ensures avl(?T2) andBool tree_keys(?T2) ==K { V } U tree_keys(T1)
66+
andBool tree_height(T1) <=Int tree_height(?T2)
67+
andBool tree_height(?T2) <=Int tree_height(T1) +Int 1
7568
```
7669

7770
While the rule is fairly verbose (due to operating on the configuration used to
@@ -85,35 +78,34 @@ Specifically
8578
* the parts that captures general JavaScript behavior; e.g. the line
8679
`(.Bag => ?_:Bag)`
8780
in the `<objs>` cell that says that after a function call there may be some
88-
dead objects left over, since the semantics does not garbage collect (`?\_` is a
81+
dead objects left over, since the semantics does not garbage collect (`?_` is a
8982
existentially quantified anonymous variable)
90-
* the internal reference to the `insert` function, `@o(19)`, will be automatically generated.
83+
* the internal reference to the `insert` function, `@o(19)` (which can be automatically generated).
9184

9285
The parts of this rule specific to the avl insert routine are
9386
* the `<k>` cell, which says that the call to insert takes a string `V` and an
9487
object reference `O1` and returns another object reference `?O2`
9588
* the line
96-
`(string_htree(O1)(T1:StringTree) => string_htree(?O2)(?T2:StringTree))`
89+
`(htree(O1)(T1:StringTree) => htree(?O2)(?T2:StringTree))`
9790
in the `<objs>` cell which says that before the call to insert, there is a tree
9891
rooted at `O1` which represent the algebraic tree `T1` in the heap, and after the
9992
call there is another tree rooted at `?O2` which represents the tree `?T2`
100-
* the requires clause, which i) states that `T1` is an avl, ii) bounds the height
101-
of `T1` to ensure there is no precision loss when computing the height of `?T2`
102-
(the tree after the insertion), and iii) states that insert has not been
103-
redefined between the global declaration and the call site
104-
* the ensures clause which states that i) `?T2` is an avl, ii) they keys of `?T2`
93+
* the requires clause, which i) states that `T1` is an avl, and ii) bounds the
94+
height of `T1` to ensure there is no precision loss when computing the height of
95+
`?T2` (the tree after the insertion)
96+
* the ensures clause, which states that i) `?T2` is an avl, ii) the keys of `?T2`
10597
are the union of the keys of `T1` and `{ V }`, and iii) the height of `?T2`
10698
increases by at most one
10799

108100
With that in mind, we could generate the rule above from a more compact
109101
annotation
110102
```
111103
function insert(v, t)
112-
//@requires string_htree(t)(T1) /\ string_avl(T1)
113-
/\ string_tree_height(T1) < 4294967295
114-
//@ensures string_htree(t)(?T2) /\ string_avl(?T2)
115-
/\ string_tree_keys(?T2) == { V } U string_tree_keys(T1)
116-
/\ | string_tree_height(?T2) - string_tree_height(T1) | < 1
104+
//@requires htree(t)(T1) /\ avl(T1)
105+
/\ tree_height(T1) < 4294967295
106+
//@ensures htree(t)(?T2) /\ avl(?T2)
107+
/\ tree_keys(?T2) == { V } U tree_keys(T1)
108+
/\ | tree_height(?T2) - tree_height(T1) | < 1
117109
```
118110

119111
We did not implement this transformation yet. However a similar transformation
@@ -139,6 +131,7 @@ module JS-VERIFIER
139131
endmodule
140132
```
141133

134+
142135
### Directory Structure
143136

144137
* [patterns](patterns) - definitions of the abstractions used in the specifications (list, tree, etc) given in K syntax

‎verification/avl/avl_delete_spec.k‎

Lines changed: 20 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ rule
2929
(.Bag => ?_:Bag)
3030
...</envs>
3131
<objs>...
32-
string_htree(O)(T:StringTree)
32+
htree(O)(T:StringTree)
3333
OBJS:Bag
3434
(.Bag => ?_:Bag)
3535
...</objs>
@@ -40,9 +40,9 @@ rule
4040
Undefined,
4141
@Cons(O:NullableObject, @Nil))
4242
=>
43-
string_tree_height(T)
43+
tree_height(T)
4444
...</k>
45-
requires string_avl(T) andBool (string_tree_height(T) <Int 4294967296)
45+
requires avl(T) andBool (tree_height(T) <Int 4294967296)
4646

4747
rule
4848
<envs>...
@@ -53,19 +53,19 @@ rule
5353
<obj>
5454
<oid> O </oid>
5555
<properties>
56-
"value" |-> @desc("Value" |-> S:String "Writable" |-> true "Enumerable" |-> true "Configurable" |-> true)
57-
"height" |-> @desc((("Value" |-> _:Int) => ("Value" |-> string_tree_height(string_node(S:String, TL:StringTree, TR:StringTree)))) "Writable" |-> true "Enumerable" |-> true "Configurable" |-> true)
58-
"left" |-> @desc("Value" |-> OL:NullableObject "Writable" |-> true "Enumerable" |-> true "Configurable" |-> true)
59-
"right" |-> @desc("Value" |-> OR:NullableObject "Writable" |-> true "Enumerable" |-> true "Configurable" |-> true)
56+
"value" |-> @desc("Value" |-> S:String "Writable" |-> true "Enumerable" |-> true "Configurable" |-> true)
57+
"height" |-> @desc((("Value" |-> _:Int) => ("Value" |-> tree_height(node(S:String, TL:StringTree, TR:StringTree)))) "Writable" |-> true "Enumerable" |-> true "Configurable" |-> true)
58+
"left" |-> @desc("Value" |-> OL:NullableObject "Writable" |-> true "Enumerable" |-> true "Configurable" |-> true)
59+
"right" |-> @desc("Value" |-> OR:NullableObject "Writable" |-> true "Enumerable" |-> true "Configurable" |-> true)
6060
</properties>
6161
<internalProperties>
6262
"Class" |-> "Object"
6363
"Extensible" |-> true
6464
"Prototype" |-> @ObjectProtoOid
6565
</internalProperties>
6666
</obj>
67-
string_htree(OL)(TL:StringTree)
68-
string_htree(OR)(TR:StringTree)
67+
htree(OL)(TL:StringTree)
68+
htree(OR)(TR:StringTree)
6969
OBJS:Bag
7070
(.Bag => ?_:Bag)
7171
...</objs>
@@ -78,17 +78,17 @@ rule
7878
=>
7979
Undefined
8080
...</k>
81-
requires (string_avl(TL)) andBool (string_avl(TR))
82-
andBool (string_tree_height(TL) <Int (4294967296 -Int 1))
83-
andBool (string_tree_height(TR) <Int (4294967296 -Int 1))
81+
requires avl(TL) andBool avl(TR)
82+
andBool (tree_height(TL) <Int (4294967296 -Int 1))
83+
andBool (tree_height(TR) <Int (4294967296 -Int 1))
8484

8585
rule
8686
<envs>...
8787
ENVS:Bag
8888
(.Bag => ?_:Bag)
8989
...</envs>
9090
<objs>...
91-
string_htree(O)(T:StringTree)
91+
htree(O)(T:StringTree)
9292
OBJS:Bag
9393
(.Bag => ?_:Bag)
9494
...</objs>
@@ -101,16 +101,16 @@ rule
101101
=>
102102
?M:String
103103
...</k>
104-
requires string_avl(T)
105-
ensures (?M inStringSet string_tree_keys(T)) andBool ({ ?M } <=StringSet string_tree_keys(T))
104+
requires avl(T)
105+
ensures (?M inStringSet tree_keys(T)) andBool ({ ?M } <=StringSet tree_keys(T))
106106

107107
rule
108108
<envs>...
109109
ENVS:Bag
110110
(.Bag => ?_:Bag)
111111
...</envs>
112112
<objs>...
113-
(string_htree(O1)(T1:StringTree) => string_htree(?O2)(?T2:StringTree))
113+
(htree(O1)(T1:StringTree) => htree(?O2)(?T2:StringTree))
114114
OBJS:Bag
115115
(.Bag => ?_:Bag)
116116
...</objs>
@@ -123,9 +123,9 @@ rule
123123
=>
124124
?O2:NullableObject
125125
...</k>
126-
requires string_avl(T1) andBool (string_tree_height(T1) <Int 4294967296)
127-
ensures string_avl(?T2) andBool string_tree_keys(?T2) ==K string_tree_keys(T1) -StringSet { V }
128-
andBool string_tree_height(T1) -Int 1 <=Int string_tree_height(?T2)
129-
andBool string_tree_height(?T2) <=Int string_tree_height(T1)
126+
requires avl(T1) andBool (tree_height(T1) <Int 4294967296)
127+
ensures avl(?T2) andBool tree_keys(?T2) ==K tree_keys(T1) -StringSet { V }
128+
andBool tree_height(T1) -Int 1 <=Int tree_height(?T2)
129+
andBool tree_height(?T2) <=Int tree_height(T1)
130130
endmodule
131131

‎verification/avl/avl_find_spec.k‎

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ rule
1010
...</envs>
1111
<objs>...
1212
OBJS:Bag
13-
string_htree(O)(T:StringTree)
13+
htree(O)(T:StringTree)
1414
(.Bag => ?_:Bag)
1515
...</objs>
1616
<k>
@@ -20,7 +20,7 @@ rule
2020
Undefined,
2121
@Cons(V:String, @Cons(O:NullableObject, @Nil)))
2222
=>
23-
V inStringSet string_tree_keys(T)
23+
V inStringSet tree_keys(T)
2424
...</k>
25-
requires string_avl(T)
25+
requires avl(T)
2626
endmodule

‎verification/avl/avl_insert_spec.k‎

Lines changed: 18 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ rule
2929
(.Bag => ?_:Bag)
3030
...</envs>
3131
<objs>...
32-
string_htree(O)(T:StringTree)
32+
htree(O)(T:StringTree)
3333
OBJS:Bag
3434
(.Bag => ?_:Bag)
3535
...</objs>
@@ -40,9 +40,9 @@ rule
4040
Undefined,
4141
@Cons(O:NullableObject, @Nil))
4242
=>
43-
string_tree_height(T)
43+
tree_height(T)
4444
...</k>
45-
requires string_avl(T) andBool (string_tree_height(T) <Int 4294967296)
45+
requires avl(T) andBool (tree_height(T) <Int 4294967296)
4646

4747
rule
4848
<envs>...
@@ -53,19 +53,19 @@ rule
5353
<obj>
5454
<oid> O </oid>
5555
<properties>
56-
"value" |-> @desc("Value" |-> S:String "Writable" |-> true "Enumerable" |-> true "Configurable" |-> true)
57-
"height" |-> @desc((("Value" |-> _:Int) => ("Value" |-> string_tree_height(string_node(S:String, TL:StringTree, TR:StringTree)))) "Writable" |-> true "Enumerable" |-> true "Configurable" |-> true)
58-
"left" |-> @desc("Value" |-> OL:NullableObject "Writable" |-> true "Enumerable" |-> true "Configurable" |-> true)
59-
"right" |-> @desc("Value" |-> OR:NullableObject "Writable" |-> true "Enumerable" |-> true "Configurable" |-> true)
56+
"value" |-> @desc("Value" |-> S:String "Writable" |-> true "Enumerable" |-> true "Configurable" |-> true)
57+
"height" |-> @desc((("Value" |-> _:Int) => ("Value" |-> tree_height(node(S:String, TL:StringTree, TR:StringTree)))) "Writable" |-> true "Enumerable" |-> true "Configurable" |-> true)
58+
"left" |-> @desc("Value" |-> OL:NullableObject "Writable" |-> true "Enumerable" |-> true "Configurable" |-> true)
59+
"right" |-> @desc("Value" |-> OR:NullableObject "Writable" |-> true "Enumerable" |-> true "Configurable" |-> true)
6060
</properties>
6161
<internalProperties>
6262
"Class" |-> "Object"
6363
"Extensible" |-> true
6464
"Prototype" |-> @ObjectProtoOid
6565
</internalProperties>
6666
</obj>
67-
string_htree(OL)(TL:StringTree)
68-
string_htree(OR)(TR:StringTree)
67+
htree(OL)(TL:StringTree)
68+
htree(OR)(TR:StringTree)
6969
OBJS:Bag
7070
(.Bag => ?_:Bag)
7171
...</objs>
@@ -78,9 +78,9 @@ rule
7878
=>
7979
Undefined
8080
...</k>
81-
requires (string_avl(TL)) andBool (string_avl(TR))
82-
andBool (string_tree_height(TL) <Int (4294967296 -Int 1))
83-
andBool (string_tree_height(TR) <Int (4294967296 -Int 1))
81+
requires avl(TL) andBool avl(TR)
82+
andBool (tree_height(TL) <Int (4294967296 -Int 1))
83+
andBool (tree_height(TR) <Int (4294967296 -Int 1))
8484

8585
rule
8686
<envs>...
@@ -89,10 +89,10 @@ rule
8989
...</envs>
9090
<objs>...
9191
OBJS:Bag
92-
string_htree(O1)(T1:StringTree)
92+
htree(O1)(T1:StringTree)
9393
=>
9494
OBJS:Bag
95-
string_htree(?O2)(?T2:StringTree)
95+
htree(?O2)(?T2:StringTree)
9696
?_:Bag
9797
...</objs>
9898
<k>
@@ -104,9 +104,9 @@ rule
104104
=>
105105
?O2:NullableObject
106106
...</k>
107-
requires string_avl(T1) andBool (string_tree_height(T1) <Int (4294967296 -Int 1))
108-
ensures string_avl(?T2) andBool string_tree_keys(?T2) ==K { V } U string_tree_keys(T1)
109-
andBool string_tree_height(T1) <=Int string_tree_height(?T2)
110-
andBool string_tree_height(?T2) <=Int string_tree_height(T1) +Int 1
107+
requires avl(T1) andBool (tree_height(T1) <Int (4294967296 -Int 1))
108+
ensures avl(?T2) andBool tree_keys(?T2) ==K { V } U tree_keys(T1)
109+
andBool tree_height(T1) <=Int tree_height(?T2)
110+
andBool tree_height(?T2) <=Int tree_height(T1) +Int 1
111111
endmodule
112112

0 commit comments

Comments
 (0)