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
fdc3b193
Commit
fdc3b193
authored
14 years ago
by
Robin Steiger
Browse files
Options
Downloads
Patches
Plain Diff
Two non-trivial bug fixes in pure scala (in pulloutAndKeepLets and inlineFunctionsAndContracts).
InsertSort.sort can now be verified.
parent
8679204a
No related branches found
No related tags found
No related merge requests found
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
src/purescala/Analysis.scala
+12
-0
12 additions, 0 deletions
src/purescala/Analysis.scala
src/purescala/Trees.scala
+38
-8
38 additions, 8 deletions
src/purescala/Trees.scala
with
50 additions
and
8 deletions
src/purescala/Analysis.scala
+
12
−
0
View file @
fdc3b193
...
@@ -166,11 +166,23 @@ object Analysis {
...
@@ -166,11 +166,23 @@ object Analysis {
val
substMap
=
Map
[
Expr
,
Expr
]((
fArgsAsVars
zip
fParamsAsLetVarVars
)
:
_
*
)
val
substMap
=
Map
[
Expr
,
Expr
]((
fArgsAsVars
zip
fParamsAsLetVarVars
)
:
_
*
)
if
(
fd
.
hasPostcondition
)
{
if
(
fd
.
hasPostcondition
)
{
val
newVar
=
Variable
(
FreshIdentifier
(
"call"
,
true
)).
setType
(
fd
.
returnType
)
val
newVar
=
Variable
(
FreshIdentifier
(
"call"
,
true
)).
setType
(
fd
.
returnType
)
/* START CHANGE */
// Code before
/*
extras = mkBigLet(And(
extras = mkBigLet(And(
replace(substMap + (ResultVariable() -> newVar), fd.postcondition.get),
replace(substMap + (ResultVariable() -> newVar), fd.postcondition.get),
Equals(newVar, FunctionInvocation(fd, fParamsAsLetVarVars).setType(fd.returnType))
Equals(newVar, FunctionInvocation(fd, fParamsAsLetVarVars).setType(fd.returnType))
)) :: extras
)) :: extras
Some(newVar)
Some(newVar)
*/
// Fixed code ?!?
extras
=
And
(
replace
(
substMap
+
(
ResultVariable
()
->
newVar
),
fd
.
postcondition
.
get
),
Equals
(
newVar
,
FunctionInvocation
(
fd
,
fParamsAsLetVarVars
).
setType
(
fd
.
returnType
))
)
::
extras
Some
(
mkBigLet
(
newVar
))
/* END CHANGE */
}
else
if
(
fd
.
hasImplementation
&&
!
program
.
isRecursive
(
fd
))
{
// means we can inline at least one level...
}
else
if
(
fd
.
hasImplementation
&&
!
program
.
isRecursive
(
fd
))
{
// means we can inline at least one level...
Some
(
mkBigLet
(
replace
(
substMap
,
fd
.
body
.
get
)))
Some
(
mkBigLet
(
replace
(
substMap
,
fd
.
body
.
get
)))
}
else
{
// we can't do much for calls to recursive functions or to functions with no bodies
}
else
{
// we can't do much for calls to recursive functions or to functions with no bodies
...
...
This diff is collapsed.
Click to expand it.
src/purescala/Trees.scala
+
38
−
8
View file @
fdc3b193
...
@@ -125,7 +125,10 @@ object Trees {
...
@@ -125,7 +125,10 @@ object Trees {
/* For all types that don't have their own XXXEquals */
/* For all types that don't have their own XXXEquals */
object
Equals
{
object
Equals
{
def
apply
(
l
:
Expr
,
r
:
Expr
)
:
Equals
=
new
Equals
(
l
,
r
)
def
apply
(
l
:
Expr
,
r
:
Expr
)
:
Expr
=
(
l
.
getType
,
r
.
getType
)
match
{
case
(
BooleanType
,
BooleanType
)
=>
Iff
(
l
,
r
)
case
_
=>
new
Equals
(
l
,
r
)
}
def
unapply
(
e
:
Equals
)
:
Option
[(
Expr
,
Expr
)]
=
if
(
e
==
null
)
None
else
Some
((
e
.
left
,
e
.
right
))
def
unapply
(
e
:
Equals
)
:
Option
[(
Expr
,
Expr
)]
=
if
(
e
==
null
)
None
else
Some
((
e
.
left
,
e
.
right
))
}
}
...
@@ -272,9 +275,9 @@ object Trees {
...
@@ -272,9 +275,9 @@ object Trees {
object
BinaryOperator
{
object
BinaryOperator
{
def
unapply
(
expr
:
Expr
)
:
Option
[(
Expr
,
Expr
,
(
Expr
,
Expr
)
=>
Expr
)]
=
expr
match
{
def
unapply
(
expr
:
Expr
)
:
Option
[(
Expr
,
Expr
,
(
Expr
,
Expr
)
=>
Expr
)]
=
expr
match
{
case
Equals
(
t1
,
t2
)
=>
Some
((
t1
,
t2
,
Equals
(
_
,
_
)
))
case
Equals
(
t1
,
t2
)
=>
Some
((
t1
,
t2
,
Equals
.
apply
))
case
Iff
(
t1
,
t2
)
=>
Some
((
t1
,
t2
,
Iff
))
case
Iff
(
t1
,
t2
)
=>
Some
((
t1
,
t2
,
Iff
))
case
Implies
(
t1
,
t2
)
=>
Some
((
t1
,
t2
,
((
e1
,
e2
)
=>
Implies
(
e1
,
e2
))
))
case
Implies
(
t1
,
t2
)
=>
Some
((
t1
,
t2
,
Implies
.
apply
))
case
Plus
(
t1
,
t2
)
=>
Some
((
t1
,
t2
,
Plus
))
case
Plus
(
t1
,
t2
)
=>
Some
((
t1
,
t2
,
Plus
))
case
Minus
(
t1
,
t2
)
=>
Some
((
t1
,
t2
,
Minus
))
case
Minus
(
t1
,
t2
)
=>
Some
((
t1
,
t2
,
Minus
))
case
Times
(
t1
,
t2
)
=>
Some
((
t1
,
t2
,
Times
))
case
Times
(
t1
,
t2
)
=>
Some
((
t1
,
t2
,
Times
))
...
@@ -308,8 +311,8 @@ object Trees {
...
@@ -308,8 +311,8 @@ object Trees {
def
unapply
(
expr
:
Expr
)
:
Option
[(
Seq
[
Expr
]
,
(
Seq
[
Expr
])
=>
Expr
)]
=
expr
match
{
def
unapply
(
expr
:
Expr
)
:
Option
[(
Seq
[
Expr
]
,
(
Seq
[
Expr
])
=>
Expr
)]
=
expr
match
{
case
FunctionInvocation
(
fd
,
args
)
=>
Some
((
args
,
FunctionInvocation
(
fd
,
_
)))
case
FunctionInvocation
(
fd
,
args
)
=>
Some
((
args
,
FunctionInvocation
(
fd
,
_
)))
case
CaseClass
(
cd
,
args
)
=>
Some
((
args
,
CaseClass
(
cd
,
_
)))
case
CaseClass
(
cd
,
args
)
=>
Some
((
args
,
CaseClass
(
cd
,
_
)))
case
And
(
args
)
=>
Some
((
args
,
And
(
_
)
))
case
And
(
args
)
=>
Some
((
args
,
And
.
apply
))
case
Or
(
args
)
=>
Some
((
args
,
Or
(
_
)
))
case
Or
(
args
)
=>
Some
((
args
,
Or
.
apply
))
case
FiniteSet
(
args
)
=>
Some
((
args
,
FiniteSet
))
case
FiniteSet
(
args
)
=>
Some
((
args
,
FiniteSet
))
case
FiniteMultiset
(
args
)
=>
Some
((
args
,
FiniteMultiset
))
case
FiniteMultiset
(
args
)
=>
Some
((
args
,
FiniteMultiset
))
case
_
=>
None
case
_
=>
None
...
@@ -321,20 +324,21 @@ object Trees {
...
@@ -321,20 +324,21 @@ object Trees {
case
Not
(
e
)
=>
e
case
Not
(
e
)
=>
e
case
Iff
(
e1
,
e2
)
=>
Iff
(
negate
(
e1
),
e2
)
case
Iff
(
e1
,
e2
)
=>
Iff
(
negate
(
e1
),
e2
)
case
Implies
(
e1
,
e2
)
=>
And
(
e1
,
negate
(
e2
))
case
Implies
(
e1
,
e2
)
=>
And
(
e1
,
negate
(
e2
))
case
Or
(
exs
)
=>
And
(
exs
.
map
(
negate
(
_
))
)
case
Or
(
exs
)
=>
And
(
exs
map
negate
)
case
And
(
exs
)
=>
Or
(
exs
.
map
(
negate
(
_
))
)
case
And
(
exs
)
=>
Or
(
exs
map
negate
)
case
LessThan
(
e1
,
e2
)
=>
GreaterEquals
(
e1
,
e2
)
case
LessThan
(
e1
,
e2
)
=>
GreaterEquals
(
e1
,
e2
)
case
LessEquals
(
e1
,
e2
)
=>
GreaterThan
(
e1
,
e2
)
case
LessEquals
(
e1
,
e2
)
=>
GreaterThan
(
e1
,
e2
)
case
GreaterThan
(
e1
,
e2
)
=>
LessEquals
(
e1
,
e2
)
case
GreaterThan
(
e1
,
e2
)
=>
LessEquals
(
e1
,
e2
)
case
GreaterEquals
(
e1
,
e2
)
=>
LessThan
(
e1
,
e2
)
case
GreaterEquals
(
e1
,
e2
)
=>
LessThan
(
e1
,
e2
)
case
i
@
IfExpr
(
c
,
e1
,
e2
)
=>
IfExpr
(
c
,
negate
(
e1
),
negate
(
e2
)).
setType
(
i
.
getType
)
case
i
@
IfExpr
(
c
,
e1
,
e2
)
=>
IfExpr
(
c
,
negate
(
e1
),
negate
(
e2
)).
setType
(
i
.
getType
)
case
BooleanLiteral
(
b
)
=>
BooleanLiteral
(!
b
)
case
_
=>
Not
(
expr
)
case
_
=>
Not
(
expr
)
}
}
// Warning ! This may loop forever if the substitutions are not
// Warning ! This may loop forever if the substitutions are not
// well-formed!
// well-formed!
def
replace
(
substs
:
Map
[
Expr
,
Expr
],
expr
:
Expr
)
:
Expr
=
{
def
replace
(
substs
:
Map
[
Expr
,
Expr
],
expr
:
Expr
)
:
Expr
=
{
searchAndReplace
(
substs
.
get
(
_
)
)(
expr
)
searchAndReplace
(
substs
.
get
)(
expr
)
}
}
def
searchAndReplace
(
subst
:
Expr
=>
Option
[
Expr
],
recursive
:
Boolean
=
true
)(
expr
:
Expr
)
:
Expr
=
{
def
searchAndReplace
(
subst
:
Expr
=>
Option
[
Expr
],
recursive
:
Boolean
=
true
)(
expr
:
Expr
)
:
Expr
=
{
...
@@ -447,6 +451,9 @@ object Trees {
...
@@ -447,6 +451,9 @@ object Trees {
rebuildLets
(
storedLets
,
noLets
)
rebuildLets
(
storedLets
,
noLets
)
}
}
/* START CHANGE */
// Previous code (keep this if nested lets can only appear in the body)
/*
def pulloutAndKeepLets(expr: Expr) : (Seq[(Identifier,Expr)], Expr) = {
def pulloutAndKeepLets(expr: Expr) : (Seq[(Identifier,Expr)], Expr) = {
var storedLets: List[(Identifier,Expr)] = Nil
var storedLets: List[(Identifier,Expr)] = Nil
...
@@ -463,6 +470,29 @@ object Trees {
...
@@ -463,6 +470,29 @@ object Trees {
val noLets = searchAndReplace(killLet)(expr)
val noLets = searchAndReplace(killLet)(expr)
(storedLets, noLets)
(storedLets, noLets)
}
}
*/
// new code (keep this if nested lets can appear in the value part, too)
def
pulloutAndKeepLets
(
expr
:
Expr
)
:
(
List
[(
Identifier
,
Expr
)],
Expr
)
=
{
var
storedLets
:
List
[(
Identifier
,
Expr
)]
=
Nil
def
storeLet
(
t
:
Expr
)
:
Option
[
Expr
]
=
t
match
{
case
l
@
Let
(
i
,
e
,
b
)
=>
// Easy fix, but breaks define-before-use order !!
//val noLets = searchAndReplace(storeLet)(e)
//storedLets ::= i -> noLets
// Better fix, but please check
val
(
stored
,
value
)
=
pulloutAndKeepLets
(
e
)
storedLets
:::=
stored
storedLets
::=
i
->
value
Some
(
b
)
case
_
=>
None
}
val
noLets
=
searchAndReplace
(
storeLet
)(
expr
)
(
storedLets
,
noLets
)
}
/* END CHANGE */
def
rebuildLets
(
lets
:
Seq
[(
Identifier
,
Expr
)],
expr
:
Expr
)
:
Expr
=
{
def
rebuildLets
(
lets
:
Seq
[(
Identifier
,
Expr
)],
expr
:
Expr
)
:
Expr
=
{
lets
.
foldLeft
(
expr
)((
e
,
p
)
=>
Let
(
p
.
_1
,
p
.
_2
,
e
))
lets
.
foldLeft
(
expr
)((
e
,
p
)
=>
Let
(
p
.
_1
,
p
.
_2
,
e
))
...
...
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