Skip to content

Commit f389208

Browse files
authored
Merge branch 'master' into meilers_precise_quantified_fields
2 parents 4a57829 + f261bcc commit f389208

2 files changed

Lines changed: 46 additions & 2 deletions

File tree

src/main/scala/viper/silver/ast/Program.scala

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ case class Program(domains: Seq[Domain], fields: Seq[Field], functions: Seq[Func
3636
checkMethodCallsAreValid ++
3737
checkFunctionApplicationsAreValid ++
3838
checkDomainFunctionApplicationsAreValid ++
39+
checkPredicateAccessesAreValid ++
3940
checkAbstractPredicatesUsage ++
4041
checkIdentifiers
4142

@@ -114,6 +115,28 @@ case class Program(domains: Seq[Domain], fields: Seq[Field], functions: Seq[Func
114115
s
115116
}
116117

118+
/** Checks that the predicate access arguments are assignable to formalArgs.
119+
**/
120+
lazy val checkPredicateAccessesAreValid: Seq[ConsistencyError] = {
121+
var s = Seq.empty[ConsistencyError]
122+
123+
for (predAcc@PredicateAccess(args, name) <- this) {
124+
this.findPredicateOptionally(name) match {
125+
case None => // Consistency error already reported by checkIdentifiers
126+
case Some(predDef) => {
127+
if (!Consistency.areAssignable(args, predDef.formalArgs)) {
128+
s :+= ConsistencyError(
129+
s"Predicate $name with formal arguments ${predDef.formalArgs} cannot be used with provided arguments $args.",
130+
predAcc.pos
131+
)
132+
}
133+
}
134+
}
135+
}
136+
137+
s
138+
}
139+
117140
/** Checks that the applied domain functions exists, that the arguments of function applications are assignable to
118141
* formalArgs, that the type of function applications matches with the type of the function definition and that also
119142
* the name of the domain matches.
@@ -264,6 +287,8 @@ case class Program(domains: Seq[Domain], fields: Seq[Field], functions: Seq[Func
264287
}
265288
}
266289

290+
def findPredicateOptionally(name: String): Option[Predicate] = this.predicates.find(_.name == name)
291+
267292
def findPredicate(name: String): Predicate = {
268293
this.predicates.find(_.name == name) match {
269294
case Some(p) => p

src/test/scala/ConsistencyTests.scala

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,13 @@ class ConsistencyTests extends AnyFunSuite with Matchers {
127127
body = None
128128
)()
129129

130+
val pred =
131+
Predicate(
132+
name = "P",
133+
formalArgs = Seq(LocalVarDecl("x", Int)()),
134+
body = None
135+
)()
136+
130137
val callerIntVarDecl = LocalVarDecl("intRes", Int)()
131138
val callerIntVar = LocalVar("intRes", Int)()
132139
val callerBoolVarDecl = LocalVarDecl("boolRes", Bool)()
@@ -147,23 +154,35 @@ class ConsistencyTests extends AnyFunSuite with Matchers {
147154
Seq()
148155
)()
149156

157+
val callerPosts =
158+
Seq(
159+
// Wrong: zero arguments
160+
PredicateAccessPredicate(PredicateAccess(Seq(), "P")(), FullPerm()())(),
161+
// Wrong: wrong argument type
162+
PredicateAccessPredicate(PredicateAccess(Seq(callerBoolVar), "P")(), FullPerm()())(),
163+
// Correct
164+
PredicateAccessPredicate(PredicateAccess(Seq(callerIntVar), "P")(), FullPerm()())()
165+
)
166+
150167
val caller =
151168
Method(
152169
name = "caller",
153170
formalArgs = Seq(),
154171
formalReturns = Seq(callerIntVarDecl, callerBoolVarDecl),
155172
pres = Seq(),
156-
posts = Seq(),
173+
posts = callerPosts,
157174
body = Some(callerBody)
158175
)()
159176

160177
val program =
161-
Program(domains = Seq(), fields = Seq(), functions = Seq(func), predicates = Seq(), methods = Seq(caller), extensions = Seq())()
178+
Program(domains = Seq(), fields = Seq(), functions = Seq(func), predicates = Seq(pred), methods = Seq(caller), extensions = Seq())()
162179

163180
program.checkTransitively shouldBe Seq(
164181
ConsistencyError("Function f with formal arguments List(x: Int) cannot be applied to provided arguments List().", NoPosition),
165182
ConsistencyError("No matching function f found of return type Bool, instead found with return type Int.", NoPosition),
166183
ConsistencyError("Function f with formal arguments List(x: Int) cannot be applied to provided arguments List(boolRes).", NoPosition),
184+
ConsistencyError("Predicate P with formal arguments List(x: Int) cannot be used with provided arguments List().", NoPosition),
185+
ConsistencyError("Predicate P with formal arguments List(x: Int) cannot be used with provided arguments List(boolRes).", NoPosition),
167186
ConsistencyError("No matching identifier g found of type Function.", NoPosition)
168187
)
169188
}

0 commit comments

Comments
 (0)