Skip to content

Commit 452c47c

Browse files
authored
Merge pull request #604 from viperproject/meilers_precise_quantified_fields
Ignore quantified fields/predicates in bodies of called methods
2 parents f261bcc + f389208 commit 452c47c

1 file changed

Lines changed: 41 additions & 28 deletions

File tree

src/main/scala/viper/silver/ast/utility/QuantifiedPermissions.scala

Lines changed: 41 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -53,39 +53,33 @@ object QuantifiedPermissions {
5353
* e.g. someMethod.quantifiedFields.
5454
*/
5555

56-
def quantifiedFields(root: Node, program: Program): collection.Set[Field] = {
56+
def quantifiedFields(root: Member, program: Program): collection.Set[Field] = {
5757
val collected = mutable.LinkedHashSet[Field]()
5858
val visited = mutable.Set[Member]()
5959
val toVisit = mutable.Queue[Member]()
6060

61-
root match {
62-
case m: Member => toVisit += m
63-
case _ =>
64-
}
61+
toVisit += root
6562

6663
toVisit ++= Nodes.referencedMembers(root, program)
6764

68-
quantifiedFields(toVisit, collected, visited, program)
65+
quantifiedFields(toVisit, root, collected, visited, program)
6966

7067
collected
7168
}
7269

7370
/* TODO: See comment above about caching
7471
* TODO: Unify with corresponding code for fields
7572
*/
76-
def quantifiedPredicates(root: Node, program: Program): collection.Set[Predicate] = {
73+
def quantifiedPredicates(root: Member, program: Program): collection.Set[Predicate] = {
7774
val collected = mutable.LinkedHashSet[Predicate]()
7875
val visited = mutable.Set[Member]()
7976
val toVisit = mutable.Queue[Member]()
8077

81-
root match {
82-
case m: Member => toVisit += m
83-
case _ =>
84-
}
78+
toVisit += root
8579

8680
toVisit ++= Nodes.referencedMembers(root, program)
8781

88-
quantifiedPredicates(toVisit, collected, visited, program)
82+
quantifiedPredicates(toVisit, root, collected, visited, program)
8983

9084
collected
9185
}
@@ -98,44 +92,63 @@ object QuantifiedPermissions {
9892
}
9993

10094
private def quantifiedFields(toVisit: mutable.Queue[Member],
95+
root: Member,
10196
collected: mutable.LinkedHashSet[Field],
10297
visited: mutable.Set[Member],
10398
program: Program): Unit = {
10499

105100
while (toVisit.nonEmpty) {
106-
val root = toVisit.dequeue()
101+
val currentRoot = toVisit.dequeue()
107102

108-
root visit {
109-
case QuantifiedPermissionAssertion(_, _, acc: FieldAccessPredicate) =>
110-
collected += acc.loc.field
111-
case Forall(_,triggers,_) => collected ++= triggers flatMap (_.exps) collect {case fa: FieldAccess => fa.field}
103+
val relevantNodes: Seq[Node] = currentRoot match {
104+
case m@Method(_, _, _, pres, posts, _) if m != root =>
105+
// use only specification of called methods
106+
pres ++ posts
107+
case _ => Seq(currentRoot)
112108
}
113109

114-
visited += root
110+
visited += currentRoot
115111

116-
utility.Nodes.referencedMembers(root, program) foreach (m =>
117-
if (!visited.contains(m)) toVisit += m)
112+
for (n <- relevantNodes){
113+
n visit {
114+
case QuantifiedPermissionAssertion(_, _, acc: FieldAccessPredicate) =>
115+
collected += acc.loc.field
116+
case Forall(_,triggers,_) => collected ++= triggers flatMap (_.exps) collect {case fa: FieldAccess => fa.field}
117+
}
118+
utility.Nodes.referencedMembers(n, program) foreach (m =>
119+
if (!visited.contains(m)) toVisit += m)
120+
}
118121
}
119122
}
120123

121124
private def quantifiedPredicates(toVisit: mutable.Queue[Member],
125+
root: Member,
122126
collected: mutable.LinkedHashSet[Predicate],
123127
visited: mutable.Set[Member],
124128
program: Program): Unit = {
125129

126130
while (toVisit.nonEmpty) {
127-
val root = toVisit.dequeue()
131+
val currentRoot = toVisit.dequeue()
128132

129-
root visit {
130-
case QuantifiedPermissionAssertion(_, _, acc: PredicateAccessPredicate) =>
131-
collected += program.findPredicate(acc.loc.predicateName)
132-
case Forall(_,triggers,_) => collected ++= triggers flatMap (_.exps) collect {case pa: PredicateAccess => pa.loc(program)}
133+
val relevantNodes: Seq[Node] = currentRoot match {
134+
case m@Method(_, _, _, pres, posts, _) if m != root =>
135+
// use only specification of called methods
136+
pres ++ posts
137+
case _ => Seq(currentRoot)
133138
}
134139

135-
visited += root
140+
visited += currentRoot
141+
142+
for (n <- relevantNodes){
143+
n visit {
144+
case QuantifiedPermissionAssertion(_, _, acc: PredicateAccessPredicate) =>
145+
collected += program.findPredicate(acc.loc.predicateName)
146+
case Forall(_,triggers,_) => collected ++= triggers flatMap (_.exps) collect {case pa: PredicateAccess => pa.loc(program)}
147+
}
148+
utility.Nodes.referencedMembers(n, program) foreach (m =>
149+
if (!visited.contains(m)) toVisit += m)
136150

137-
utility.Nodes.referencedMembers(root, program) foreach (m =>
138-
if (!visited.contains(m)) toVisit += m)
151+
}
139152
}
140153
}
141154

0 commit comments

Comments
 (0)