Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
I
inox
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Wiki
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Build
Pipelines
Jobs
Pipeline schedules
Artifacts
Deploy
Releases
Package registry
Model registry
Operate
Environments
Terraform modules
Monitor
Incidents
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
LARA
inox
Commits
9215b774
Commit
9215b774
authored
9 years ago
by
Regis Blanc
Browse files
Options
Downloads
Patches
Plain Diff
fix fd closure when PC calls other nested fd
parent
d41909c2
Branches
Branches containing commit
Tags
Tags containing commit
No related merge requests found
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
src/main/scala/leon/purescala/FunctionClosure.scala
+26
-8
26 additions, 8 deletions
src/main/scala/leon/purescala/FunctionClosure.scala
src/test/resources/regression/verification/purescala/valid/Nested17.scala
+23
-0
23 additions, 0 deletions
...es/regression/verification/purescala/valid/Nested17.scala
with
49 additions
and
8 deletions
src/main/scala/leon/purescala/FunctionClosure.scala
+
26
−
8
View file @
9215b774
...
@@ -42,22 +42,40 @@ object FunctionClosure extends TransformationPhase {
...
@@ -42,22 +42,40 @@ object FunctionClosure extends TransformationPhase {
case
FunctionInvocation
(
TypedFunDef
(
fd
,
_
),
_
)
if
nestedFuns
.
contains
(
fd
)
=>
case
FunctionInvocation
(
TypedFunDef
(
fd
,
_
),
_
)
if
nestedFuns
.
contains
(
fd
)
=>
fd
fd
}
}
f
->
calls
val
pcCalls
=
functionCallsOf
(
nestedWithPaths
(
f
))
collect
{
case
FunctionInvocation
(
TypedFunDef
(
fd
,
_
),
_
)
if
nestedFuns
.
contains
(
fd
)
=>
fd
}
f
->
(
calls
++
pcCalls
)
}.
toMap
}.
toMap
)
)
//println("nested funs: " + nestedFuns)
//println("call graph: " + callGraph)
def
freeVars
(
fd
:
FunDef
,
pc
:
Expr
)
:
Set
[
Identifier
]
=
def
freeVars
(
fd
:
FunDef
)
:
Set
[
Identifier
]
=
variablesOf
(
fd
.
fullBody
)
--
fd
.
paramIds
variablesOf
(
fd
.
fullBody
)
++
variablesOf
(
pc
)
--
fd
.
paramIds
// All free variables one should include.
// All free variables one should include.
// Contains free vars of the function itself plus of all transitively called functions.
// Contains free vars of the function itself plus of all transitively called functions.
val
transFree
=
nestedFuns
.
map
{
fd
=>
// also contains free vars from PC if the PC is relevant to the fundef
fd
->
(
callGraph
(
fd
)
+
fd
).
flatMap
(
(
fd2
:
FunDef
)
=>
freeVars
(
fd2
,
nestedWithPaths
(
fd2
))
).
toSeq
val
transFree
=
{
}.
toMap
def
step
(
current
:
Map
[
FunDef
,
Set
[
Identifier
]])
:
Map
[
FunDef
,
Set
[
Identifier
]]
=
{
nestedFuns
.
map
(
fd
=>
{
val
transFreeVars
=
(
callGraph
(
fd
)
+
fd
).
flatMap
((
fd2
:
FunDef
)
=>
freeVars
(
fd2
))
val
reqPaths
=
Seq
(
nestedWithPaths
(
fd
)).
filter
(
pathExpr
=>
exists
{
case
_
=>
true
//TODO: for now we take all PCs, need to refine
//case Variable(id) => transFreeVars.contains(id)
//case _ => false
}(
pathExpr
))
(
fd
,
transFreeVars
++
reqPaths
.
flatMap
(
p
=>
variablesOf
(
p
))
--
fd
.
paramIds
)
}).
toMap
}
utils
.
fixpoint
(
step
,
-
1
)(
nestedFuns
.
map
(
fd
=>
(
fd
,
freeVars
(
fd
))).
toMap
)
}.
map
(
p
=>
(
p
.
_1
,
p
.
_2
.
toSeq
))
//println("free vars: " + transFree)
// Closed functions along with a map (old var -> new var).
// Closed functions along with a map (old var -> new var).
val
closed
=
nestedWithPaths
.
map
{
val
closed
=
nestedWithPaths
.
map
{
case
(
inner
,
pc
)
=>
inner
->
step
(
inner
,
fd
,
pc
,
transFree
(
inner
))
case
(
inner
,
pc
)
=>
inner
->
closeFd
(
inner
,
fd
,
pc
,
transFree
(
inner
))
}
}
// Remove LetDefs from fd
// Remove LetDefs from fd
...
@@ -123,7 +141,7 @@ object FunctionClosure extends TransformationPhase {
...
@@ -123,7 +141,7 @@ object FunctionClosure extends TransformationPhase {
)
)
// Takes one inner function and closes it.
// Takes one inner function and closes it.
private
def
step
(
inner
:
FunDef
,
outer
:
FunDef
,
pc
:
Expr
,
free
:
Seq
[
Identifier
])
:
FunSubst
=
{
private
def
closeFd
(
inner
:
FunDef
,
outer
:
FunDef
,
pc
:
Expr
,
free
:
Seq
[
Identifier
])
:
FunSubst
=
{
val
tpFresh
=
outer
.
tparams
map
{
_
.
freshen
}
val
tpFresh
=
outer
.
tparams
map
{
_
.
freshen
}
val
tparamsMap
=
outer
.
tparams
.
zip
(
tpFresh
map
{
_
.
tp
}).
toMap
val
tparamsMap
=
outer
.
tparams
.
zip
(
tpFresh
map
{
_
.
tp
}).
toMap
...
...
This diff is collapsed.
Click to expand it.
src/test/resources/regression/verification/purescala/valid/Nested17.scala
0 → 100644
+
23
−
0
View file @
9215b774
package
test.resources.regression.verification.purescala.valid
/* Copyright 2009-2016 EPFL, Lausanne */
object
Nested17
{
def
test
(
y
:
Int
)
=
{
def
g
()
=
y
//this will be in the path condition of h with a function call to g
val
b
=
g
()
//the tricky part is to capture the free variables of g since the
//path condition contains a function invocation to g
def
h
()
:
Unit
=
{
()
}
ensuring
(
res
=>
true
)
h
()
}
}
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment