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
b7d0f616
Commit
b7d0f616
authored
8 years ago
by
Nicolas Voirol
Browse files
Options
Downloads
Patches
Plain Diff
Better quantifier instantiation optimizations
parent
3877a916
No related branches found
No related tags found
No related merge requests found
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
src/main/scala/inox/solvers/unrolling/QuantificationTemplates.scala
+51
-18
51 additions, 18 deletions
...cala/inox/solvers/unrolling/QuantificationTemplates.scala
with
51 additions
and
18 deletions
src/main/scala/inox/solvers/unrolling/QuantificationTemplates.scala
+
51
−
18
View file @
b7d0f616
...
@@ -248,7 +248,7 @@ trait QuantificationTemplates { self: Templates =>
...
@@ -248,7 +248,7 @@ trait QuantificationTemplates { self: Templates =>
def
unroll
:
Clauses
=
{
def
unroll
:
Clauses
=
{
val
imClauses
=
new
scala
.
collection
.
mutable
.
ListBuffer
[
Encoded
]
val
imClauses
=
new
scala
.
collection
.
mutable
.
ListBuffer
[
Encoded
]
for
(
e
@
(
gen
,
bs
,
m
)
<-
ignoredMatchers
.
toSeq
if
gen
<=
currentGeneration
)
{
for
(
e
@
(
gen
,
bs
,
m
)
<-
ignoredMatchers
.
toSeq
if
gen
<=
currentGeneration
)
{
imClauses
++=
instantiateMatcher
(
bs
,
m
)
imClauses
++=
instantiateMatcher
(
bs
,
m
,
defer
=
true
)
ignoredMatchers
-=
e
ignoredMatchers
-=
e
}
}
...
@@ -263,7 +263,7 @@ trait QuantificationTemplates { self: Templates =>
...
@@ -263,7 +263,7 @@ trait QuantificationTemplates { self: Templates =>
ignoredSubsts
+=
q
->
keep
ignoredSubsts
+=
q
->
keep
for
((
_
,
bs
,
subst
)
<-
release
)
{
for
((
_
,
bs
,
subst
)
<-
release
)
{
suClauses
++=
q
.
instantiateSubst
(
bs
,
subst
)
suClauses
++=
q
.
instantiateSubst
(
bs
,
subst
,
defer
=
true
)
}
}
}
}
...
@@ -293,18 +293,18 @@ trait QuantificationTemplates { self: Templates =>
...
@@ -293,18 +293,18 @@ trait QuantificationTemplates { self: Templates =>
}
}
def
instantiateMatcher
(
blocker
:
Encoded
,
matcher
:
Matcher
)
:
Clauses
=
{
def
instantiateMatcher
(
blocker
:
Encoded
,
matcher
:
Matcher
)
:
Clauses
=
{
instantiateMatcher
(
Set
(
blocker
),
matcher
)
instantiateMatcher
(
Set
(
blocker
),
matcher
,
false
)
}
}
@inline
@inline
private
def
instantiateMatcher
(
blockers
:
Set
[
Encoded
],
matcher
:
Matcher
)
:
Clauses
=
{
private
def
instantiateMatcher
(
blockers
:
Set
[
Encoded
],
matcher
:
Matcher
,
defer
:
Boolean
=
false
)
:
Clauses
=
{
val
relevantBlockers
=
blockerPath
(
blockers
)
val
relevantBlockers
=
blockerPath
(
blockers
)
if
(
handledMatchers
(
relevantBlockers
->
matcher
))
{
if
(
handledMatchers
(
relevantBlockers
->
matcher
))
{
Seq
.
empty
Seq
.
empty
}
else
{
}
else
{
handledMatchers
+=
relevantBlockers
->
matcher
handledMatchers
+=
relevantBlockers
->
matcher
quantifications
.
flatMap
(
_
.
instantiate
(
relevantBlockers
,
matcher
))
quantifications
.
flatMap
(
_
.
instantiate
(
relevantBlockers
,
matcher
,
defer
))
}
}
}
}
...
@@ -509,7 +509,29 @@ trait QuantificationTemplates { self: Templates =>
...
@@ -509,7 +509,29 @@ trait QuantificationTemplates { self: Templates =>
def
clear
()
:
Unit
=
for
(
gs
<-
grounds
.
values
)
gs
.
clear
()
def
clear
()
:
Unit
=
for
(
gs
<-
grounds
.
values
)
gs
.
clear
()
def
reset
()
:
Unit
=
for
(
gs
<-
grounds
.
values
)
gs
.
reset
()
def
reset
()
:
Unit
=
for
(
gs
<-
grounds
.
values
)
gs
.
reset
()
def
instantiate
(
bs
:
Set
[
Encoded
],
m
:
Matcher
)
:
Clauses
=
{
private
val
optimizationQuorums
:
Seq
[
Set
[
Matcher
]]
=
{
def
matchersOf
(
m
:
Matcher
)
:
Set
[
Matcher
]
=
m
.
args
.
flatMap
{
case
Right
(
m
)
=>
matchersOf
(
m
)
+
m
case
_
=>
Set
.
empty
[
Matcher
]
}.
toSet
def
quantifiersOf
(
m
:
Matcher
)
:
Set
[
Encoded
]
=
(
matchersOf
(
m
)
+
m
).
flatMap
(
_
.
args
.
collect
{
case
Left
(
q
)
if
quantified
(
q
)
=>
q
})
val
allMatchers
=
matchers
.
flatMap
(
_
.
_2
).
toList
val
allQuorums
=
allMatchers
.
toSet
.
subsets
.
filter
(
ms
=>
ms
.
flatMap
(
quantifiersOf
)
==
quantified
)
.
filterNot
(
ms
=>
allMatchers
.
exists
{
m
=>
!
ms
(
m
)
&&
{
val
common
=
ms
&
matchersOf
(
m
)
common
.
nonEmpty
&&
(
quantifiersOf
(
m
)
--
common
.
flatMap
(
quantifiersOf
)).
nonEmpty
}
})
allQuorums
.
foldLeft
(
Seq
[
Set
[
Matcher
]]())((
qs
,
q
)
=>
if
(
qs
.
exists
(
_
subsetOf
q
))
qs
else
qs
:+
q
)
}
def
instantiate
(
bs
:
Set
[
Encoded
],
m
:
Matcher
,
defer
:
Boolean
=
false
)
:
Clauses
=
{
generationCounter
+=
1
generationCounter
+=
1
val
gen
=
generationCounter
val
gen
=
generationCounter
...
@@ -531,7 +553,7 @@ trait QuantificationTemplates { self: Templates =>
...
@@ -531,7 +553,7 @@ trait QuantificationTemplates { self: Templates =>
(
key
,
i
)
<-
constraints
;
(
key
,
i
)
<-
constraints
;
perfect
<-
correspond
(
matcherKey
(
m
),
key
)
perfect
<-
correspond
(
matcherKey
(
m
),
key
)
if
!
grounds
(
q
)(
bs
,
m
.
args
(
i
)))
{
if
!
grounds
(
q
)(
bs
,
m
.
args
(
i
)))
{
val
initGens
:
Set
[
Int
]
=
if
(
perfect
)
Set
.
empty
else
Set
(
gen
)
val
initGens
:
Set
[
Int
]
=
if
(
perfect
&&
!
defer
)
Set
.
empty
else
Set
(
gen
)
val
newMappings
=
(
quantified
-
q
).
foldLeft
(
Seq
((
bs
,
Map
(
q
->
m
.
args
(
i
)),
initGens
,
0
)))
{
val
newMappings
=
(
quantified
-
q
).
foldLeft
(
Seq
((
bs
,
Map
(
q
->
m
.
args
(
i
)),
initGens
,
0
)))
{
case
(
maps
,
oq
)
=>
for
{
case
(
maps
,
oq
)
=>
for
{
(
bs
,
map
,
gens
,
c
)
<-
maps
(
bs
,
map
,
gens
,
c
)
<-
maps
...
@@ -546,7 +568,21 @@ trait QuantificationTemplates { self: Templates =>
...
@@ -546,7 +568,21 @@ trait QuantificationTemplates { self: Templates =>
/* @nv: I tried some smarter cost computations here but it turns out that the
/* @nv: I tried some smarter cost computations here but it turns out that the
* overhead needed to determine when to optimize exceeds the benefits */
* overhead needed to determine when to optimize exceeds the benefits */
mappings
++=
newMappings
.
map
{
case
(
bs
,
map
,
gens
,
c
)
=>
mappings
++=
newMappings
.
map
{
case
(
bs
,
map
,
gens
,
c
)
=>
(
bs
,
map
,
c
+
(
3
*
map
.
values
.
collect
{
case
Right
(
m
)
=>
totalDepth
(
m
)
}.
sum
))
val
substituter
=
mkSubstituter
(
map
.
mapValues
(
_
.
encoded
))
val
msubst
=
map
.
collect
{
case
(
q
,
Right
(
m
))
=>
q
->
m
}
val
isOpt
=
optimizationQuorums
.
exists
{
ms
=>
ms
.
forall
(
m
=>
handledMatchers
.
contains
(
m
.
substitute
(
substituter
,
msubst
)))
}
val
cost
=
if
(
initGens
.
nonEmpty
)
{
1
+
3
*
map
.
values
.
collect
{
case
Right
(
m
)
=>
totalDepth
(
m
)
}.
sum
}
else
if
(!
isOpt
)
{
3
}
else
{
0
}
(
bs
,
map
,
c
+
cost
)
}
}
// register ground instantiation for future instantiations
// register ground instantiation for future instantiations
...
@@ -600,14 +636,14 @@ trait QuantificationTemplates { self: Templates =>
...
@@ -600,14 +636,14 @@ trait QuantificationTemplates { self: Templates =>
val
gen
=
currentGeneration
+
delay
+
(
if
(
getPolarity
.
isEmpty
)
2
else
0
)
val
gen
=
currentGeneration
+
delay
+
(
if
(
getPolarity
.
isEmpty
)
2
else
0
)
ignoredSubsts
+=
this
->
(
ignoredSubsts
.
getOrElse
(
this
,
Set
.
empty
)
+
((
gen
,
bs
,
subst
)))
ignoredSubsts
+=
this
->
(
ignoredSubsts
.
getOrElse
(
this
,
Set
.
empty
)
+
((
gen
,
bs
,
subst
)))
}
else
{
}
else
{
instantiation
++=
instantiateSubst
(
bs
,
subst
)
instantiation
++=
instantiateSubst
(
bs
,
subst
,
defer
=
false
)
}
}
}
}
instantiation
.
toSeq
instantiation
.
toSeq
}
}
def
instantiateSubst
(
bs
:
Set
[
Encoded
],
subst
:
Map
[
Encoded
,
Arg
])
:
Clauses
=
{
def
instantiateSubst
(
bs
:
Set
[
Encoded
],
subst
:
Map
[
Encoded
,
Arg
]
,
defer
:
Boolean
=
false
)
:
Clauses
=
{
handledSubsts
+=
this
->
(
handledSubsts
.
getOrElse
(
this
,
Set
.
empty
)
+
(
bs
->
subst
))
handledSubsts
+=
this
->
(
handledSubsts
.
getOrElse
(
this
,
Set
.
empty
)
+
(
bs
->
subst
))
val
instantiation
=
new
scala
.
collection
.
mutable
.
ListBuffer
[
Encoded
]
val
instantiation
=
new
scala
.
collection
.
mutable
.
ListBuffer
[
Encoded
]
...
@@ -630,14 +666,11 @@ trait QuantificationTemplates { self: Templates =>
...
@@ -630,14 +666,11 @@ trait QuantificationTemplates { self: Templates =>
val
sb
=
bs
++
(
if
(
b
==
guard
)
Set
.
empty
else
Set
(
substituter
(
b
)))
val
sb
=
bs
++
(
if
(
b
==
guard
)
Set
.
empty
else
Set
(
substituter
(
b
)))
val
sm
=
m
.
substitute
(
substituter
,
msubst
)
val
sm
=
m
.
substitute
(
substituter
,
msubst
)
def
abs
(
i
:
Int
)
:
Int
=
if
(
i
<
0
)
-
i
else
i
if
(
b
!=
guard
)
{
val
totalDelay
=
2
*
(
abs
(
totalDepth
(
sm
)
-
totalDepth
(
m
))
+
(
if
(
b
==
guard
)
0
else
1
))
val
gen
=
currentGeneration
+
1
if
(
totalDelay
>
0
)
{
val
gen
=
currentGeneration
+
totalDelay
ignoredMatchers
+=
((
gen
,
sb
,
sm
))
ignoredMatchers
+=
((
gen
,
sb
,
sm
))
}
else
{
}
else
{
instantiation
++=
instantiateMatcher
(
sb
,
sm
)
instantiation
++=
instantiateMatcher
(
sb
,
sm
,
defer
=
defer
)
}
}
}
}
...
@@ -883,7 +916,7 @@ trait QuantificationTemplates { self: Templates =>
...
@@ -883,7 +916,7 @@ trait QuantificationTemplates { self: Templates =>
val
freshSubst
=
mkSubstituter
(
template
.
quantifiers
.
map
(
p
=>
p
.
_2
->
encodeSymbol
(
p
.
_1
)).
toMap
)
val
freshSubst
=
mkSubstituter
(
template
.
quantifiers
.
map
(
p
=>
p
.
_2
->
encodeSymbol
(
p
.
_1
)).
toMap
)
for
((
b
,
ms
)
<-
template
.
matchers
;
m
<-
ms
)
{
for
((
b
,
ms
)
<-
template
.
matchers
;
m
<-
ms
)
{
clauses
++=
instantiateMatcher
(
Set
.
empty
[
Encoded
],
m
)
clauses
++=
instantiateMatcher
(
Set
.
empty
[
Encoded
],
m
,
false
)
// it is very rare that such instantiations are actually required, so we defer them
// it is very rare that such instantiations are actually required, so we defer them
val
gen
=
currentGeneration
+
20
val
gen
=
currentGeneration
+
20
ignoredMatchers
+=
((
gen
,
Set
(
b
),
m
.
substitute
(
freshSubst
,
Map
.
empty
)))
ignoredMatchers
+=
((
gen
,
Set
(
b
),
m
.
substitute
(
freshSubst
,
Map
.
empty
)))
...
@@ -996,7 +1029,7 @@ trait QuantificationTemplates { self: Templates =>
...
@@ -996,7 +1029,7 @@ trait QuantificationTemplates { self: Templates =>
val
valuesP
=
values
.
map
(
v
=>
v
->
encodeSymbol
(
v
))
val
valuesP
=
values
.
map
(
v
=>
v
->
encodeSymbol
(
v
))
val
exprT
=
mkEncoder
(
elemsP
.
toMap
++
valuesP
+
guardP
)(
expr
)
val
exprT
=
mkEncoder
(
elemsP
.
toMap
++
valuesP
+
guardP
)(
expr
)
val
disjunction
=
handledSubsts
(
q
)
match
{
val
disjunction
=
handledSubsts
.
getOrElse
(
q
,
Set
.
empty
)
match
{
case
set
if
set
.
isEmpty
=>
mkEncoder
(
Map
.
empty
)(
BooleanLiteral
(
false
))
case
set
if
set
.
isEmpty
=>
mkEncoder
(
Map
.
empty
)(
BooleanLiteral
(
false
))
case
set
=>
mkOr
(
set
.
toSeq
.
map
{
case
(
enablers
,
subst
)
=>
case
set
=>
mkOr
(
set
.
toSeq
.
map
{
case
(
enablers
,
subst
)
=>
val
b
=
if
(
enablers
.
isEmpty
)
trueT
else
mkAnd
(
enablers
.
toSeq
:
_
*
)
val
b
=
if
(
enablers
.
isEmpty
)
trueT
else
mkAnd
(
enablers
.
toSeq
:
_
*
)
...
...
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