Skip to content

Commit 93bc9b7

Browse files
authored
Merge pull request #802 from viperproject/meilers_dont_count_requires_as_pre
Allow domain axioms to use functions that have decreases clauses
2 parents aa72715 + 0769bf5 commit 93bc9b7

2 files changed

Lines changed: 75 additions & 1 deletion

File tree

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

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
package viper.silver.parser
88

99
import viper.silver.FastMessaging
10+
import viper.silver.parser.PKw.Requires
1011

1112
import scala.collection.mutable
1213

@@ -685,8 +686,13 @@ case class TypeChecker(names: NameAnalyser) {
685686
check(fd.typ)
686687
fd.formalArgs foreach (a => check(a.typ))
687688
}
688-
if (pfa.isDescendant[PAxiom] && pfn.pres.length != 0)
689+
if (pfa.isDescendant[PAxiom] && pfn.pres.toSeq.exists(pre => pre.k.rs == Requires)) {
690+
// A domain axiom, which must always be well-defined, is calling a function that has at least
691+
// one real precondition (i.e., not just a requires clause or something similar that's
692+
// temporarily represented as a precondition), which means that the call may not always be
693+
// well-defined. This is not allowed.
689694
issueError(func, s"Cannot use function ${func.name}, which has preconditions, inside axiom")
695+
}
690696

691697
case pdf: PDomainFunction =>
692698
val domain = pdf.domain
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
// Any copyright is dedicated to the Public Domain.
2+
// http://creativecommons.org/publicdomain/zero/1.0/
3+
4+
5+
function f1(i: Int): Int
6+
decreases i
7+
requires i > -2
8+
{
9+
i > 0 ? 1 + f1(i - 1) : 0
10+
}
11+
12+
function f2(i: Int): Int
13+
decreases i
14+
{
15+
i > 0 ? 1 + f2(i - 1) : 0
16+
}
17+
18+
function f3(i: Int): Int
19+
decreases i
20+
ensures result >= 0
21+
{
22+
i > 0 ? 1 + f3(i - 1) : 0
23+
}
24+
25+
function f4(i: Int): Int
26+
ensures result >= 0
27+
decreases _
28+
{
29+
i > 0 ? 1 + f4(i - 1) : 0
30+
}
31+
32+
function f5(i: Int): Int
33+
requires i > -2
34+
decreases i
35+
ensures result >= 0
36+
{
37+
i > 0 ? 1 + f5(i - 1) : 0
38+
}
39+
40+
domain t {
41+
function fAlias1(Int): Int
42+
function fAlias2(Int): Int
43+
function fAlias3(Int): Int
44+
function fAlias4(Int): Int
45+
function fAlias5(Int): Int
46+
47+
axiom {
48+
//:: ExpectedOutput(typechecker.error)
49+
forall i: Int :: f1(i) == fAlias1(i)
50+
}
51+
52+
axiom {
53+
forall i: Int :: f2(i) == fAlias2(i)
54+
}
55+
56+
axiom {
57+
forall i: Int :: f3(i) == fAlias3(i)
58+
}
59+
60+
axiom {
61+
forall i: Int :: f4(i) == fAlias4(i)
62+
}
63+
64+
axiom {
65+
//:: ExpectedOutput(typechecker.error)
66+
forall i: Int :: f5(i) == fAlias5(i)
67+
}
68+
}

0 commit comments

Comments
 (0)