Skip to content

Commit b51e0dc

Browse files
authored
Merge pull request #698 from viperproject/meilers_allow_heapdep_func_calls
Allow calls of non-domain functions without preconditions from domain axioms
2 parents 496dcdc + 3ec8900 commit b51e0dc

5 files changed

Lines changed: 109 additions & 7 deletions

File tree

src/main/scala/viper/silver/parser/Resolver.scala

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -658,13 +658,13 @@ case class TypeChecker(names: NameAnalyser) {
658658
pfa.function = fd
659659
ensure(fd.formalArgs.size == args.size, pfa, "wrong number of arguments")
660660
fd match {
661-
case PFunction(_, _, _, _, _, _) =>
661+
case PFunction(_, _, _, pres, _, _) =>
662662
checkMember(fd) {
663663
check(fd.typ)
664664
fd.formalArgs foreach (a => check(a.typ))
665665
}
666-
if (inAxiomScope(Some(pfa)))
667-
issueError(func, func.name + " is not a domain function")
666+
if (inAxiomScope(Some(pfa)) && pres.nonEmpty)
667+
issueError(func, s"Cannot use function ${func.name}, which has preconditions, inside axiom")
668668

669669
case pdf@PDomainFunction(_, _, _, _, _) =>
670670
val domain = names.definition(curMember)(pdf.domainName).get.asInstanceOf[PDomain]
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
// Any copyright is dedicated to the Public Domain.
2+
// http://creativecommons.org/publicdomain/zero/1.0/
3+
4+
function interp(i: Int): Int
5+
{
6+
i + 1
7+
}
8+
9+
domain d {
10+
function unint(i: Int): Int
11+
12+
axiom {
13+
forall i: Int :: {unint(i)} unint(i) == interp(i) + 1
14+
}
15+
}
16+
17+
method huh()
18+
{
19+
assert unint(4) == 6
20+
21+
//:: ExpectedOutput(assert.failed:assertion.false)
22+
assert unint(14) == 14
23+
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
// Any copyright is dedicated to the Public Domain.
2+
// http://creativecommons.org/publicdomain/zero/1.0/
3+
4+
function interp(i: Int): Int
5+
requires i > 5
6+
{
7+
i + 1
8+
}
9+
10+
domain d {
11+
function unint(i: Int): Int
12+
13+
axiom {
14+
//:: ExpectedOutput(typechecker.error)
15+
forall i: Int :: {unint(i)} unint(i) == interp(i) + 1
16+
}
17+
}
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
// Any copyright is dedicated to the Public Domain.
2+
// http://creativecommons.org/publicdomain/zero/1.0/
3+
4+
field f: Int
5+
6+
function interp(i: Int): Int
7+
{
8+
i + 1
9+
}
10+
11+
function uninterp(i: Int): Int
12+
ensures result == i + 4
13+
14+
function heapDep(r: Ref): Int
15+
requires acc(r.f)
16+
{
17+
r.f + 2
18+
}
19+
20+
function heapDep2(r: Ref): Int
21+
requires acc(r.f)
22+
{
23+
heapDep(r) + heapDepUnint(r) + 10
24+
}
25+
26+
function heapDepUnint(r: Ref): Int
27+
requires acc(r.f)
28+
ensures result == r.f + 3
29+
30+
domain d {
31+
function dfunc(i: Int): Int
32+
33+
function dfunc2(i: Int): Int
34+
35+
axiom {
36+
forall i: Int :: {dfunc(i)} dfunc(i) == interp(i) + 5
37+
}
38+
39+
axiom {
40+
forall i: Int :: {dfunc2(i)} dfunc2(i) == uninterp(i) + 7
41+
}
42+
}
43+
44+
method main()
45+
{
46+
var x: Ref
47+
x := new(f)
48+
var y: Ref
49+
y := new(f)
50+
51+
x.f := 20
52+
y.f := 3
53+
assert dfunc2(x.f) == 31
54+
assert heapDep2(x) == 15 + 20 + 20
55+
56+
assert dfunc(x.f + 1) == 27
57+
assert interp(34) == 35
58+
assert heapDep(y) + dfunc2(x.f + 5) == 41
59+
60+
//:: ExpectedOutput(assert.failed:assertion.false)
61+
assert heapDepUnint(x) == 24
62+
}

src/test/resources/all/issues/silver/0238.vpr

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
// Any copyright is dedicated to the Public Domain.
2-
// http://creativecommons.org/publicdomain/zero/1.0/
3-
1+
// Any copyright is dedicated to the Public Domain.
2+
// http://creativecommons.org/publicdomain/zero/1.0/
3+
44
// Test case 1
55
domain A1 {
66
axiom x1 {
@@ -26,7 +26,6 @@ function q2(s:Int) : Bool
2626
// Example 3
2727
domain A3 {
2828
axiom x3 {
29-
//:: ExpectedOutput(typechecker.error)
3029
g3()
3130
}
3231
}
@@ -45,6 +44,7 @@ domain A4 {
4544
}
4645

4746
function g4(): Bool
47+
requires true
4848

4949
// Example 5
5050
domain A5 {

0 commit comments

Comments
 (0)