Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
N
NIWO
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Packages
Packages
Container Registry
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Christian Müller
NIWO
Commits
2c08691d
Commit
2c08691d
authored
Mar 06, 2019
by
Christian Müller
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
update transformations
parent
5e41de33
Changes
19
Hide whitespace changes
Inline
Side-by-side
Showing
19 changed files
with
145 additions
and
114 deletions
+145
-114
src/main/scala/de/tum/workflows/Encoding.scala
src/main/scala/de/tum/workflows/Encoding.scala
+1
-1
src/main/scala/de/tum/workflows/ExampleWorkflows.scala
src/main/scala/de/tum/workflows/ExampleWorkflows.scala
+2
-2
src/main/scala/de/tum/workflows/InvariantCLI.scala
src/main/scala/de/tum/workflows/InvariantCLI.scala
+2
-2
src/main/scala/de/tum/workflows/InvariantInspector.scala
src/main/scala/de/tum/workflows/InvariantInspector.scala
+2
-2
src/main/scala/de/tum/workflows/MainInvariants.scala
src/main/scala/de/tum/workflows/MainInvariants.scala
+2
-2
src/main/scala/de/tum/workflows/MainInvariantsInference.scala
...main/scala/de/tum/workflows/MainInvariantsInference.scala
+3
-3
src/main/scala/de/tum/workflows/MainInvariantsInterpolation.scala
.../scala/de/tum/workflows/MainInvariantsInterpolation.scala
+3
-3
src/main/scala/de/tum/workflows/MainLTL.scala
src/main/scala/de/tum/workflows/MainLTL.scala
+3
-3
src/main/scala/de/tum/workflows/Preconditions.scala
src/main/scala/de/tum/workflows/Preconditions.scala
+64
-59
src/main/scala/de/tum/workflows/Utils.scala
src/main/scala/de/tum/workflows/Utils.scala
+1
-1
src/main/scala/de/tum/workflows/WorkflowParser.scala
src/main/scala/de/tum/workflows/WorkflowParser.scala
+1
-1
src/main/scala/de/tum/workflows/blocks/Workflow.scala
src/main/scala/de/tum/workflows/blocks/Workflow.scala
+42
-16
src/main/scala/de/tum/workflows/foltl/Properties.scala
src/main/scala/de/tum/workflows/foltl/Properties.scala
+4
-4
src/main/scala/de/tum/workflows/synth/Model.scala
src/main/scala/de/tum/workflows/synth/Model.scala
+3
-3
src/main/scala/de/tum/workflows/toz3/InvariantChecker.scala
src/main/scala/de/tum/workflows/toz3/InvariantChecker.scala
+3
-3
src/main/scala/de/tum/workflows/toz3/InvariantGenerator.scala
...main/scala/de/tum/workflows/toz3/InvariantGenerator.scala
+2
-2
src/test/scala/de/tum/workflows/tests/EncodingTest.scala
src/test/scala/de/tum/workflows/tests/EncodingTest.scala
+3
-3
src/test/scala/de/tum/workflows/tests/ParserTest.scala
src/test/scala/de/tum/workflows/tests/ParserTest.scala
+3
-3
src/test/scala/de/tum/workflows/tests/Z3LTLTest.scala
src/test/scala/de/tum/workflows/tests/Z3LTLTest.scala
+1
-1
No files found.
src/main/scala/de/tum/workflows/Encoding.scala
View file @
2c08691d
...
...
@@ -209,7 +209,7 @@ object Encoding extends LazyLogging {
val
MAXINVLENGTH
=
800
def
toDot
(
g
:
WorkflowGraph
,
elaboration
:
Option
[(
InvProperties
,
Spec
)]
=
None
)(
labels
:
Map
[
Int
,
String
],
edges
:
Set
[
g.EdgeT
])
=
{
def
toDot
(
g
:
WorkflowGraph
,
elaboration
:
Option
[(
InvProperties
,
NI
Spec
)]
=
None
)(
labels
:
Map
[
Int
,
String
],
edges
:
Set
[
g.EdgeT
])
=
{
val
root
=
DotRootGraph
(
directed
=
true
,
id
=
Some
(
"Invariant Labelling"
))
...
...
src/main/scala/de/tum/workflows/ExampleWorkflows.scala
View file @
2c08691d
...
...
@@ -25,7 +25,7 @@ object ExampleWorkflows extends LazyLogging {
(
sublists
toMap
)
++
here
}
def
parseExample
(
s
:
String
)
:
Option
[
Spec
]
=
{
def
parseExample
(
s
:
String
)
:
Option
[
NI
Spec
]
=
{
if
(!
examples
.
contains
(
s
))
{
logger
.
error
(
s
"$s not contained in list of examples"
)
None
...
...
@@ -47,7 +47,7 @@ object ExampleWorkflows extends LazyLogging {
}
}
def
parsedExamples
(
prefix
:
String
,
folder
:
File
)
:
Map
[
String
,
Spec
]
=
{
def
parsedExamples
(
prefix
:
String
,
folder
:
File
)
:
Map
[
String
,
NI
Spec
]
=
{
val
map
=
for
((
name
,
f
)
<-
examples
)
yield
{
val
s
=
Source
.
fromFile
(
f
).
mkString
val
spec
=
WorkflowParser
.
parseSpec
(
s
)
...
...
src/main/scala/de/tum/workflows/InvariantCLI.scala
View file @
2c08691d
...
...
@@ -5,7 +5,7 @@ import scala.io.Source
import
com.typesafe.scalalogging.LazyLogging
import
de.tum.workflows.Utils._
import
de.tum.workflows.blocks.Spec
import
de.tum.workflows.blocks.
NI
Spec
import
de.tum.workflows.toz3.InvariantChecker
import
de.tum.workflows.toz3.InvariantGenerator
import
de.tum.workflows.toz3.InvProperties
...
...
@@ -55,7 +55,7 @@ object InvariantCLI extends App with LazyLogging {
spec
.
map
(
generate
(
new
File
(
file
).
getName
.
stripSuffix
(
".spec"
),
_
,
properties
))
}
def
generate
(
name
:
String
,
spec
:
Spec
,
properties
:
InvProperties
)
{
def
generate
(
name
:
String
,
spec
:
NI
Spec
,
properties
:
InvProperties
)
{
logger
.
info
(
s
"Encoding Spec:\n$spec"
)
def
invariant
=
InvariantGenerator
.
invariantNoninterSingleBS
(
spec
)
...
...
src/main/scala/de/tum/workflows/InvariantInspector.scala
View file @
2c08691d
...
...
@@ -11,7 +11,7 @@ import de.tum.workflows.foltl.Properties
import
java.io.PrintWriter
import
java.io.File
import
de.tum.workflows.blocks.Workflow
import
de.tum.workflows.blocks.Spec
import
de.tum.workflows.blocks.
NI
Spec
import
de.tum.workflows.foltl.FormulaFunctions
import
de.tum.workflows.toz3.InvariantChecker
import
de.tum.workflows.toz3.InvariantGenerator
...
...
@@ -38,7 +38,7 @@ object InvariantInspector extends App with LazyLogging {
val
(
t
,
(
res
,
dot
))
=
time
{
// InvariantChecker.checkInvariantOnce(spec.w, inv(spec), true)
val
props
=
InvProperties
(
stubborn
=
false
,
eliminateA
ux
=
true
)
val
props
=
InvProperties
(
stubborn
=
false
,
eliminateA
=
true
)
val
(
result
,
graph
,
afterlabels
,
proven
,
dot
,
time
)
=
InvariantChecker
.
checkInvariantFPLabelling
(
spec
,
invariant
(
spec
),
props
)
...
...
src/main/scala/de/tum/workflows/MainInvariants.scala
View file @
2c08691d
...
...
@@ -8,14 +8,14 @@ import de.tum.workflows.Utils._
import
java.io.PrintWriter
import
java.io.File
import
de.tum.workflows.blocks.Workflow
import
de.tum.workflows.blocks.Spec
import
de.tum.workflows.blocks.
NI
Spec
import
de.tum.workflows.foltl.FormulaFunctions
import
de.tum.workflows.toz3.InvariantChecker
import
de.tum.workflows.toz3.InvariantGenerator
object
MainInvariants
extends
App
with
LazyLogging
{
def
generate
(
name
:
String
,
spec
:
Spec
)
{
def
generate
(
name
:
String
,
spec
:
NI
Spec
)
{
logger
.
info
(
s
"Encoding Spec:\n$spec"
)
def
invariant
=
...
...
src/main/scala/de/tum/workflows/MainInvariantsInference.scala
View file @
2c08691d
...
...
@@ -4,7 +4,7 @@ import com.typesafe.scalalogging.LazyLogging
import
com.microsoft.z3.Status
import
com.typesafe.scalalogging.LazyLogging
import
de.tum.workflows.Utils._
import
de.tum.workflows.blocks.
{
SimpleBlock
,
Spec
}
import
de.tum.workflows.blocks.
{
SimpleBlock
,
NI
Spec
}
import
de.tum.workflows.foltl.FOLTL._
import
de.tum.workflows.foltl.FOTransformers
import
de.tum.workflows.synth.Model
...
...
@@ -16,7 +16,7 @@ import Implicits._
object
MainInvariantsInference
extends
App
with
LazyLogging
{
def
generate
(
name
:
String
,
spec
:
Spec
,
tar
:
Int
)
{
def
generate
(
name
:
String
,
spec
:
NI
Spec
,
tar
:
Int
)
{
logger
.
info
(
s
"Encoding Spec:\n$spec"
)
def
invariant
=
...
...
@@ -30,7 +30,7 @@ object MainInvariantsInference extends App with LazyLogging {
val
props
=
InvProperties
(
stubborn
=
true
,
eliminateA
ux
=
true
,
eliminateA
=
true
,
eliminateB
=
true
)
...
...
src/main/scala/de/tum/workflows/MainInvariantsInterpolation.scala
View file @
2c08691d
...
...
@@ -3,7 +3,7 @@ package de.tum.workflows
import
com.microsoft.z3.Status
import
com.typesafe.scalalogging.LazyLogging
import
de.tum.workflows.Utils._
import
de.tum.workflows.blocks.
{
SimpleBlock
,
Spec
}
import
de.tum.workflows.blocks.
{
SimpleBlock
,
NI
Spec
}
import
de.tum.workflows.foltl.FOLTL._
import
de.tum.workflows.foltl.FOTransformers
import
de.tum.workflows.synth.Model
...
...
@@ -15,7 +15,7 @@ import Implicits._
object
MainInvariantsInterpolation
extends
App
with
LazyLogging
{
def
generate
(
name
:
String
,
spec
:
Spec
,
tar
:
Int
)
{
def
generate
(
name
:
String
,
spec
:
NI
Spec
,
tar
:
Int
)
{
logger
.
info
(
s
"Encoding Spec:\n$spec"
)
def
invariant
=
...
...
@@ -24,7 +24,7 @@ object MainInvariantsInterpolation extends App with LazyLogging {
// InvariantChecker.invariantNoninterStubborn _
// InvariantChecker.invariantAllEqual _
val
props
=
InvProperties
(
stubborn
=
false
,
eliminateA
ux
=
true
)
val
props
=
InvProperties
(
stubborn
=
false
,
eliminateA
=
true
)
val
inv
=
invariant
(
spec
)
val
(
res
,
graph
,
labels
,
t
)
=
InvariantChecker
.
checkInvariantFPHeadLabel
(
spec
,
inv
,
props
)
...
...
src/main/scala/de/tum/workflows/MainLTL.scala
View file @
2c08691d
...
...
@@ -5,7 +5,7 @@ import com.typesafe.scalalogging.LazyLogging
import
de.tum.workflows.foltl.FOTransformers
import
de.tum.workflows.Utils._
import
de.tum.workflows.foltl.Properties
import
de.tum.workflows.blocks.Spec
import
de.tum.workflows.blocks.
NI
Spec
import
de.tum.workflows.foltl.FormulaFunctions
import
de.tum.workflows.foltl.FOTransformers
import
de.tum.workflows.owltransformer.OwlTransformer
...
...
@@ -15,7 +15,7 @@ import owl.ltl.rewriter.SimplifierFactory
object
MainLTL
extends
App
with
LazyLogging
{
def
writeExample
(
name
:
String
,
spec
:
Spec
,
prop
:
Formula
)
{
def
writeExample
(
name
:
String
,
spec
:
NI
Spec
,
prop
:
Formula
)
{
val
MAX_AGENTS
=
8
...
...
@@ -69,7 +69,7 @@ object MainLTL extends App with LazyLogging {
write
(
name
,
s
"$name.metrics"
,
metrics
.
mkString
(
""
,
"\n"
,
"\n"
))
}
def
generate
(
name
:
String
,
spec
:
Spec
,
onlystubborn
:
Boolean
)
{
def
generate
(
name
:
String
,
spec
:
NI
Spec
,
onlystubborn
:
Boolean
)
{
logger
.
info
(
s
"Encoding Spec:\n$spec"
)
val
t1
=
"pi1"
val
t2
=
"pi2"
...
...
src/main/scala/de/tum/workflows/Preconditions.scala
View file @
2c08691d
...
...
@@ -9,11 +9,35 @@ import de.tum.workflows.toz3.{InvProperties, Z3BSFO}
object
Preconditions
extends
LazyLogging
{
private
def
elaborateSteps
(
b
:
SimpleBlock
,
s
:
Spec
)
:
List
[
SimpleBlock
]
=
{
private
def
elaborateSteps
(
b
:
SimpleBlock
,
spec
:
NISpec
,
properties
:
InvProperties
)
:
List
[
SimpleBlock
]
=
{
val
guardfix
=
if
(!
b
.
isoracly
&&
b
.
pred
.
isDefined
)
{
// is "normal" may block
val
choice
=
Fun
(
b
.
pred
.
get
,
b
.
agents
)
for
(
s
<-
b
.
steps
)
yield
{
val
first
=
s
.
tuple
.
head
val
inner
=
if
(
first
.
typ
==
spec
.
target
.
params
.
head
.
typ
)
{
val
inf
=
Fun
(
INFNAME
,
List
(
b
.
agents
.
head
))
if
(
properties
.
stubborn
)
{
choice
.
in
(
T1
)
}
else
{
Or
(
And
(
Neg
(
inf
.
in
(
T1
)),
choice
.
in
(
T1
)),
And
(
inf
.
in
(
T1
),
choice
))
}
}
else
{
choice
}
val
newguard
=
And
(
s
.
guard
,
inner
)
s
.
updateGuard
(
newguard
)
}
}
else
{
b
.
steps
}
val
newsteps
=
for
(
stmt
<-
b
.
steps
if
s
.
causals
.
map
(
_
.
typ
).
contains
(
stmt
.
tuple
.
head
.
typ
)
||
stmt
.
tuple
.
head
.
typ
==
s
.
target
.
params
.
head
.
typ
)
yield
{
if
s
pec
.
causals
.
map
(
_
.
typ
).
contains
(
stmt
.
tuple
.
head
.
typ
)
||
stmt
.
tuple
.
head
.
typ
==
s
pec
.
target
.
params
.
head
.
typ
)
yield
{
val
fun
=
Fun
(
stmt
.
fun
,
stmt
.
tuple
)
// TODO
val
guard
=
Neg
(
Equiv
(
fun
.
in
(
T1
),
fun
.
in
(
T2
)))
...
...
@@ -23,25 +47,40 @@ object Preconditions extends LazyLogging {
}
// For oracly blocks, remove O from guard and add to ForallMay choice predicate
private
def
elaborateOraclyBlock
(
b
:
SimpleBlock
,
s
:
Spec
)
=
{
private
def
elaborateOraclyBlock
(
b
:
SimpleBlock
,
s
pec
:
NI
Spec
)
=
{
if
(
b
.
isoracly
)
{
val
stmt
=
b
.
steps
.
head
// can only be one
def
fixguard
(
f
:
Formula
)
=
{
f
.
everywhere
{
case
f
:
Fun
if
f.isOracle
()
=>
True
}
}
def
findOracle
(
f
:
Formula
)
=
{
f
.
collect
{
case
f
:
Fun
if
(
f.isOracle
())
=>
List
(
f
.
name
)
}
}
val
name
=
findOracle
(
stmt
.
guard
).
head
val
oracles
=
findOracle
(
stmt
.
guard
)
val
name
=
oracles
.
head
if
(
oracles
.
size
!=
1
)
{
logger
.
error
(
s
"Found oracly block $b with more than one oracle"
)
}
val
choice
=
Fun
(
name
,
b
.
agents
)
def
fixguard
(
f
:
Formula
,
choice
:
Fun
)
=
{
val
nooracles
=
f
.
everywhere
{
case
f
:
Fun
if
f.isOracle
()
=>
True
}
val
decl
=
spec
.
declass
.
getOrElse
(
b
.
pred
.
get
,
(
List
(),
False
)).
_2
// FIXME: substitutions?
// FIXME: decl in T2?
And
(
nooracles
,
Or
(
And
(
decl
.
in
(
T1
),
choice
.
in
(
T1
)),
And
(
Neg
(
decl
.
in
(
T1
)),
choice
)))
}
val
newstmt
=
stmt
match
{
case
Add
(
guard
,
fun
,
tuple
)
=>
Add
(
fixguard
(
guard
).
simplify
,
fun
,
tuple
)
case
Remove
(
guard
,
fun
,
tuple
)
=>
Remove
(
fixguard
(
guard
).
simplify
,
fun
,
tuple
)
case
Add
(
guard
,
fun
,
tuple
)
=>
Add
(
fixguard
(
guard
,
choice
).
simplify
,
fun
,
tuple
)
case
Remove
(
guard
,
fun
,
tuple
)
=>
Remove
(
fixguard
(
guard
,
choice
).
simplify
,
fun
,
tuple
)
}
ForallMayBlock
(
b
.
agents
,
name
,
List
(
newstmt
))
}
else
b
...
...
@@ -66,58 +105,27 @@ object Preconditions extends LazyLogging {
})
}
// TODO: make this a transformation instead of a logics block
def
getUpdate
(
s
:
Statement
,
b
:
SimpleBlock
,
choice
:
Option
[
Fun
],
spec
:
Spec
,
properties
:
InvProperties
)
=
{
// val list = List(s.guard) ++ choice.toList
// val guard = And.make(list)
val
first
=
s
.
tuple
.
head
// Trace related substitution for informedness
val
con
=
if
(
b
.
isoracly
)
{
val
decl
=
spec
.
declass
.
getOrElse
(
b
.
pred
.
get
,
(
List
(),
False
)).
_2
// FIXME: substitutions?
// FIXME: decl in T2?
Or
(
And
(
decl
.
in
(
T1
),
choice
.
get
.
in
(
T1
)),
And
(
Neg
(
decl
.
in
(
T1
)),
choice
.
get
))
}
else
if
(
choice
.
isDefined
)
{
// is "normal" may block
val
inner
=
if
(
first
.
typ
==
spec
.
target
.
params
.
head
.
typ
)
{
val
inf
=
Fun
(
INFNAME
,
List
(
b
.
agents
.
head
))
if
(
properties
.
stubborn
)
{
choice
.
get
.
in
(
T1
)
}
else
{
Or
(
And
(
Neg
(
inf
.
in
(
T1
)),
choice
.
get
.
in
(
T1
)),
And
(
inf
.
in
(
T1
),
choice
.
get
))
}
}
else
{
choice
.
get
}
inner
}
else
{
True
}
val
guard
=
And
(
s
.
guard
,
con
).
simplify
// val guard = True
def
getUpdate
(
s
:
Statement
,
choice
:
Option
[
Fun
],
spec
:
NISpec
,
properties
:
InvProperties
)
=
{
val
frees
=
guard
.
freeVars
--
s
.
tuple
.
toSet
--
spec
.
constants
val
frees
=
s
.
guard
.
freeVars
--
s
.
tuple
.
toSet
--
spec
.
constants
val
form
=
s
match
{
case
Add
(
_
,
_
,
_
)
=>
{
Or
(
Fun
(
s
.
fun
,
s
.
tuple
),
Exists
(
frees
.
toList
,
guard
)).
simplify
Or
(
Fun
(
s
.
fun
,
s
.
tuple
),
Exists
(
frees
.
toList
,
s
.
guard
)).
simplify
}
case
Remove
(
_
,
_
,
_
)
=>
{
And
(
Fun
(
s
.
fun
,
s
.
tuple
),
Forall
(
frees
.
toList
,
Neg
(
guard
))).
simplify
And
(
Fun
(
s
.
fun
,
s
.
tuple
),
Forall
(
frees
.
toList
,
Neg
(
s
.
guard
))).
simplify
}
}
form
}
def
elaborate
(
block
:
SimpleBlock
,
spec
:
Spec
,
properties
:
InvProperties
)
=
{
val
stepOne
=
if
(!
properties
.
stubborn
)
elaborateSteps
(
block
,
spec
)
else
List
(
block
)
def
elaborate
(
block
:
SimpleBlock
,
spec
:
NI
Spec
,
properties
:
InvProperties
)
=
{
val
stepOne
=
if
(!
properties
.
stubborn
)
elaborateSteps
(
block
,
spec
,
properties
)
else
List
(
block
)
stepOne
map
{
b
=>
elaborateOraclyBlock
(
b
,
spec
)
}
}
def
weakestPrecondition
(
post
:
Formula
,
outerb
:
SimpleBlock
,
spec
:
Spec
,
properties
:
InvProperties
)
=
{
def
weakestPrecondition
(
post
:
Formula
,
outerb
:
SimpleBlock
,
spec
:
NI
Spec
,
properties
:
InvProperties
)
=
{
// TODO: Make 2-trace elaboration optional
...
...
@@ -130,13 +138,11 @@ object Preconditions extends LazyLogging {
precond
}
private
def
weakestPreconditionSingle
(
f
:
Formula
,
b
:
SimpleBlock
,
spec
:
Spec
,
properties
:
InvProperties
)
=
{
val
choice
=
b
.
pred
.
map
(
n
=>
Fun
(
n
,
b
.
agents
))
private
def
weakestPreconditionSingle
(
f
:
Formula
,
b
:
SimpleBlock
,
spec
:
NISpec
,
properties
:
InvProperties
)
=
{
val
updates
=
for
(
s
<-
b
.
steps
)
yield
{
s
.
fun
->
(
s
.
tuple
,
{
getUpdate
(
s
,
b
,
choice
,
spec
,
properties
)
getUpdate
(
s
,
b
,
spec
,
properties
)
})
}
...
...
@@ -154,7 +160,7 @@ object Preconditions extends LazyLogging {
removed
}
def
abstractedPrecondition
(
f
:
Formula
,
b
:
SimpleBlock
,
spec
:
Spec
,
properties
:
InvProperties
,
untouched
:
Set
[
String
])
=
{
def
abstractedPrecondition
(
f
:
Formula
,
b
:
SimpleBlock
,
spec
:
NI
Spec
,
properties
:
InvProperties
,
untouched
:
Set
[
String
])
=
{
val
precond
=
weakestPrecondition
(
f
,
b
,
spec
,
properties
)
// Assume untoucheds empty
...
...
@@ -171,7 +177,6 @@ object Preconditions extends LazyLogging {
z3simpednewinv
}
// Abstract away inner existentials
val
universalinv
=
if
(
removedannotations
.
toNegNf
.
hasSubFormula
{
case
e
:
Exists
=>
true
...
...
@@ -182,15 +187,15 @@ object Preconditions extends LazyLogging {
}
// Eliminate Choices
val
auxless
=
if
(
b
.
pred
.
isDefined
&&
properties
.
eliminateA
ux
)
{
val
auxless
=
if
(
b
.
pred
.
isDefined
&&
properties
.
eliminateA
)
{
FOTransformers
.
eliminateAuxiliaryPredicate
(
universalinv
,
b
.
pred
.
get
)
}
else
{
universalinv
}
// Eliminate Oracles
val
oless
=
if
(
properties
.
eliminateA
ux
)
{
val
oracles
=
spec
.
w
.
sig
.
oracle
s
.
map
(
_
.
name
)
val
oless
=
if
(
properties
.
eliminateA
)
{
val
oracles
=
spec
.
w
.
sig
.
a
s
.
map
(
_
.
name
)
oracles
.
foldRight
(
auxless
)((
b
,
inv
)
=>
FOTransformers
.
eliminateAuxiliaryPredicate
(
inv
,
b
))
}
else
{
auxless
...
...
src/main/scala/de/tum/workflows/Utils.scala
View file @
2c08691d
...
...
@@ -68,7 +68,7 @@ object Utils extends LazyLogging {
logger
.
info
(
s
"Written $file"
)
}
def
check
(
name
:
String
,
desc
:
String
,
inv
:
Formula
,
spec
:
Spec
,
properties
:
InvProperties
)
=
{
def
check
(
name
:
String
,
desc
:
String
,
inv
:
Formula
,
spec
:
NI
Spec
,
properties
:
InvProperties
)
=
{
val
model
=
if
(
properties
.
stubborn
)
"stubborn"
else
"causal"
val
basename
=
name
.
split
(
"/"
).
last
...
...
src/main/scala/de/tum/workflows/WorkflowParser.scala
View file @
2c08691d
...
...
@@ -186,7 +186,7 @@ object WorkflowParser extends RegexParsers with PackratParsers with LazyLogging
((
"Declassify"
~>
DECLASS
)?)
~
(
"Target"
~>
FUN
)
~
((
"Causality"
~>
repsep
(
TYPEDVAR
,
","
))?)
^^
{
case
_
~
w
~
decl
~
tar
~
causals
=>
Spec
(
w
,
toMap
(
decl
.
toList
),
tar
,
causals
.
getOrElse
(
List
()))
case
_
~
w
~
decl
~
tar
~
causals
=>
NISpec
(
w
,
toMap
(
decl
.
toList
),
tar
,
causals
.
getOrElse
(
List
()))
}
def
toMap
(
list
:
List
[(
Fun
,
Formula
)])
:
Map
[
String
,
(
List
[
Var
]
,
Formula
)]
=
{
...
...
src/main/scala/de/tum/workflows/blocks/Workflow.scala
View file @
2c08691d
...
...
@@ -5,14 +5,14 @@ import com.typesafe.scalalogging.LazyLogging
import
de.tum.workflows.Utils
import
de.tum.workflows.foltl.Properties
case
class
Signature
(
oracle
s
:
Set
[
Fun
],
bs
:
Set
[
Fun
],
preds
:
Set
[
Fun
])
case
class
Signature
(
as
:
Set
[
Fun
],
consta
s
:
Set
[
Fun
],
bs
:
Set
[
Fun
],
preds
:
Set
[
Fun
])
object
Signature
{
val
EMPTY
=
Signature
(
Set
(),
Set
(),
Set
())
val
EMPTY
=
Signature
(
Set
(),
Set
(),
Set
()
,
Set
()
)
}
case
class
Workflow
(
sig
:
Signature
,
steps
:
List
[
Block
])
{
override
def
toString
()
=
steps
.
mkString
(
"\n"
)
def
isomitting
=
{
lazy
val
isomitting
=
{
steps
.
exists
(
_
.
isomitting
)
}
}
...
...
@@ -20,11 +20,24 @@ object Workflow {
val
EMPTY
=
Workflow
(
Signature
.
EMPTY
,
List
())
}
case
class
Spec
(
w
:
Workflow
,
declass
:
Map
[
String
,
(
List
[
Var
]
,
Formula
)],
target
:
Fun
,
causals
:
List
[
Var
])
extends
LazyLogging
{
trait
Spec
{
def
w
:
Workflow
}
case
class
InvSpec
(
w
:
Workflow
,
always
:
Formula
,
invariant
:
Formula
)
extends
Spec
{
override
def
toString
=
{
s
"Spec\nWorkflow:\n$w\n
Declass:$declass\nTarget:$targe
t"
s
"Spec\nWorkflow:\n$w\n
Always:$always\nInvariant:$invarian
t"
}
def
toNISpec
()
=
{
NISpec
(
w
,
Map
(),
Fun
(
"NOTHING"
,
List
()),
List
())
}
}
case
class
NISpec
(
w
:
Workflow
,
declass
:
Map
[
String
,
(
List
[
Var
]
,
Formula
)],
target
:
Fun
,
causals
:
List
[
Var
])
extends
Spec
with
LazyLogging
{
override
def
toString
=
{
s
"NISpec\nWorkflow:\n$w\nDeclass:$declass\nTarget:$target"
}
lazy
val
constants
:
Set
[
Var
]
=
{
// Treat free variables in the declassification as constants
...
...
@@ -33,33 +46,39 @@ case class Spec(w: Workflow, declass: Map[String, (List[Var], Formula)], target:
}.
toSet
// TODO: How to check for more constants?
}
def
checkSanity
()
=
{
var
sane
=
true
// TODO: check all types
// TODO: check target types
// TODO: check declass arities and types (o should be an Oracle relation etc)
val
ta
=
target
.
params
.
head
// check declass bindings
for
((
o
,
(
f
,
t
))
<-
declass
if
!
t
.
freeVars
.
forall
(
v
=>
f
.
contains
(
v
)
||
(
v
==
ta
)))
{
logger
.
error
(
s
"Not all variables of the declassification condition for $o bound by the oracle"
)
sane
=
false
}
def
saneoraclestmt
(
stmt
:
Statement
,
frees
:
List
[
Var
])
=
{
// Oracle only positive
val
f
=
stmt
.
guard
.
toNegNf
val
noneg
=
!
f
.
hasSubFormula
{
case
Neg
(
f
:
Fun
)
if
f
.
isOracle
()
=>
true
}
if
(!
noneg
)
{
logger
.
error
(
s
"Found negated oracle in guard for statement $stmt"
)
}
val
allvars
=
!(
f
hasSubFormula
{
case
f
:
Fun
if
f.isOracle
&&
f.params
!=
frees
=>
true
})
if
(!
allvars
)
{
logger
.
error
(
s
"Found oracle with wrong parameters in statement $stmt"
)
}
noneg
&&
allvars
}
// check same relation only updated once per block
def
isSane
(
steps
:
List
[
Block
])
:
Boolean
=
{
val
sanes
=
steps
map
{
...
...
@@ -73,8 +92,8 @@ case class Spec(w: Workflow, declass: Map[String, (List[Var], Formula)], target:
val
saneoracly
=
if
(
b
.
isoracly
)
{
b
.
pred
.
isEmpty
&&
b
.
steps
.
size
==
1
&&
saneoraclestmt
(
b
.
steps
.
head
,
b
.
agents
)
}
else
true
//
if (!saneoracly) { logger.warn(s"Oracles used wrongly in $b") }
pred
.
isEmpty
// && saneoracly TODO: enable this later?
if
(!
saneoracly
)
{
logger
.
warn
(
s
"Oracles used wrongly in $b"
)
}
pred
.
isEmpty
&&
saneoracly
}
case
Loop
(
steps
)
=>
isSane
(
steps
)
case
NondetChoice
(
left
,
right
)
=>
isSane
(
left
)
&&
isSane
(
right
)
...
...
@@ -85,8 +104,8 @@ case class Spec(w: Workflow, declass: Map[String, (List[Var], Formula)], target:
sane
}
}
object
Spec
{
val
EMPTY
=
Spec
(
Workflow
.
EMPTY
,
Map
(),
Fun
(
"NOTHING"
,
List
()),
List
())
object
NI
Spec
{
val
EMPTY
=
NI
Spec
(
Workflow
.
EMPTY
,
Map
(),
Fun
(
"NOTHING"
,
List
()),
List
())
}
abstract
sealed
class
Block
{
...
...
@@ -98,6 +117,7 @@ abstract sealed class SimpleBlock extends Block {
def
steps
:
List
[
Statement
]
def
may
:
Boolean
def
pred
:
Option
[
String
]
def
updateSteps
(
s
:
List
[
Statement
])
override
def
isomitting
=
{
// a simple block is omitting, if there exists a statement where not all agents appear in the tuple
...
...
@@ -126,32 +146,38 @@ abstract sealed class SimpleBlock extends Block {
steps
.
map
(
_
.
fun
).
toSet
}
}
}
abstract
class
Statement
{
def
guard
:
Formula
def
fun
:
String
def
tuple
:
List
[
Var
]
def
updateGuard
(
newguard
:
Formula
)
lazy
val
freeVars
=
guard
.
freeVars
++
tuple
}
case
class
Add
(
guard
:
Formula
,
fun
:
String
,
tuple
:
List
[
Var
])
extends
Statement
{
override
def
toString
()
=
guard
+
" → "
+
fun
+
" += "
+
tuple
.
mkString
(
"("
,
","
,
")"
)
+
";"
override
def
updateGuard
(
newguard
:
Formula
)
=
Add
(
newguard
,
fun
,
tuple
)
}
case
class
Remove
(
guard
:
Formula
,
fun
:
String
,
tuple
:
List
[
Var
])
extends
Statement
{
override
def
toString
()
=
guard
+
" → "
+
fun
+
" -= "
+
tuple
.
mkString
(
"("
,
","
,
")"
)
+
";"
override
def
updateGuard
(
newguard
:
Formula
)
=
Remove
(
newguard
,
fun
,
tuple
)
}
case
class
ForallBlock
(
agents
:
List
[
Var
],
steps
:
List
[
Statement
])
extends
SimpleBlock
{
val
may
=
false
override
def
toString
()
=
"forall "
+
agents
.
map
(
_
.
withType
).
mkString
(
","
)
+
steps
.
mkString
(
"\n "
,
"\n "
,
""
)
override
def
pred
()
=
None
override
def
updateSteps
(
newsteps
:
List
[
Statement
])
=
ForallBlock
(
agents
,
newsteps
)
}
case
class
ForallMayBlock
(
agents
:
List
[
Var
],
choice
:
String
,
steps
:
List
[
Statement
])
extends
SimpleBlock
{
val
may
=
true
override
def
toString
()
=
"forall "
+
agents
.
map
(
_
.
withType
).
mkString
(
","
)
+
" may ("
+
pred
+
")"
+
steps
.
mkString
(
"\n "
,
"\n "
,
""
)
override
def
pred
()
=
Some
(
choice
)
override
def
pred
()
=
Some
(
choice
)
override
def
updateSteps
(
newsteps
:
List
[
Statement
])
=
ForallMayBlock
(
agents
,
choice
,
newsteps
)
}
case
class
Loop
(
steps
:
List
[
Block
])
extends
Block
{
...
...
src/main/scala/de/tum/workflows/foltl/Properties.scala
View file @
2c08691d
...
...
@@ -92,7 +92,7 @@ object Noninterference extends LazyLogging {
Or
.
make
(
viol
)
}
def
apply
(
choices
:
Set
[
Fun
],
spec
:
Spec
)
=
{
def
apply
(
choices
:
Set
[
Fun
],
spec
:
NI
Spec
)
=
{
val
agent
=
spec
.
target
.
params
.
head
val
samechoices
=
Stubborn
(
agent
,
choices
)
...
...
@@ -107,7 +107,7 @@ object Noninterference extends LazyLogging {
}
object
Declassification
extends
{
def
apply
(
spec
:
Spec
)
=
{
def
apply
(
spec
:
NI
Spec
)
=
{
val
sameoracles
=
for
((
o
,(
p
,
t
))
<-
spec
.
declass
)
yield
{
val
fun
=
Fun
(
o
,
None
,
p
)
// Forall fv(o). (t_T1 and t_t2) -> G (o_T1 <-> o_T2)
...
...
@@ -124,7 +124,7 @@ object Properties {
val
INFNAME
=
"informed"
// include optimizations for choices
def
noninterStubborn
(
spec
:
Spec
)
=
{
def
noninterStubborn
(
spec
:
NI
Spec
)
=
{
val
graph
=
toGraph
(
spec
.
w
)
val
cfg
=
sanecfg
(
graph
)
...
...
@@ -145,7 +145,7 @@ object Properties {
And
.
make
(
cfg
,
sem
.
in
(
T1
,
equals
),
sem
.
in
(
T2
,
equals
),
noninter
)
}
def
noninterCausal
(
spec
:
Spec
)
=
{
def
noninterCausal
(
spec
:
NI
Spec
)
=
{
val
graph
=
toGraph
(
spec
.
w
)
val
cfg
=
sanecfg
(
graph
)
...
...
src/main/scala/de/tum/workflows/synth/Model.scala
View file @
2c08691d
...
...
@@ -3,7 +3,7 @@ package de.tum.workflows.synth
import
com.microsoft.z3.Status
import
com.typesafe.scalalogging.LazyLogging
import
de.tum.workflows.Preconditions
import
de.tum.workflows.blocks.
{
SimpleBlock
,
Spec
}
import
de.tum.workflows.blocks.
{
SimpleBlock
,
NI
Spec
}
import
de.tum.workflows.foltl.FOLTL._
import
de.tum.workflows.foltl.
{
FOTransformers
,
Properties
}
import
de.tum.workflows.synth.Model.logger
...
...
@@ -30,7 +30,7 @@ case class Model(universe: Map[String, List[Var]], steering: Formula, state:Map[
And
.
make
(
formulas
.
toList
)
}
def
warp
(
b
:
SimpleBlock
,
spec
:
Spec
,
properties
:
InvProperties
)
:
Model
=
{
def
warp
(
b
:
SimpleBlock
,
spec
:
NI
Spec
,
properties
:
InvProperties
)
:
Model
=
{
val
facts
=
And
.
make
(
steering
,
stateFormula
())
// logger.info(s"Current state: ${state.pretty()}")
...
...
@@ -66,7 +66,7 @@ case class Model(universe: Map[String, List[Var]], steering: Formula, state:Map[
object
Model
extends
LazyLogging
{
def
emptystate
(
spec
:
Spec
,
universe
:
Map
[
String
,
List
[
Var
]],
props
:
InvProperties
)
=
{
def
emptystate
(
spec
:
NI
Spec
,
universe
:
Map
[
String
,
List
[
Var
]],
props
:
InvProperties
)
=
{
val
preds
=
if
(
props
.
stubborn
)
{
spec
.
w
.
sig
.
preds
.
toList
...
...
src/main/scala/de/tum/workflows/toz3/InvariantChecker.scala
View file @
2c08691d
...
...
@@ -12,9 +12,9 @@ import de.tum.workflows.foltl.FormulaFunctions
import
de.tum.workflows.Utils
import
de.tum.workflows.foltl.Properties
case
class
InvProperties
(
stubborn
:
Boolean
,
eliminateA
ux
:
Boolean
,
eliminateB
:
Boolean
=
false
)
{
}
case
class
InvProperties
(
stubborn
:
Boolean
,
eliminateA
:
Boolean
,
eliminateB
:
Boolean
=
false
)
{
}
object
InvProperties
{
val
DEFAULT
=
InvProperties
(
stubborn
=
true
,
eliminateA
ux
=
true
,
eliminateB
=
false
)
val
DEFAULT
=
InvProperties
(
stubborn
=
true
,
eliminateA
=
true
,
eliminateB
=
false
)
}
object
InvariantChecker
extends
LazyLogging
{
...
...
@@ -124,7 +124,7 @@ object InvariantChecker extends LazyLogging {
(
result
,
graph
,
labellings
.
reverse
,
proven
.
reverse
,
dot2
,
time
)
}
def
checkInvariantFPDot
(
spec
:
Spec
,
inv
:
Formula
,
properties
:
InvProperties
=
InvProperties
.
DEFAULT
)
=
{
def
checkInvariantFPDot
(
spec
:
NI
Spec
,
inv
:
Formula
,
properties
:
InvProperties
=
InvProperties
.
DEFAULT
)
=
{
val
(
result
,
graph
,
afterlabels
,
proven
,
dot
,
time
)
=
checkInvariantFPLabelling
(
spec
,
inv
,
properties
)
(
result
,
dot
,
time
)
}
...
...
src/main/scala/de/tum/workflows/toz3/InvariantGenerator.scala
View file @
2c08691d
...
...
@@ -31,7 +31,7 @@ object InvariantGenerator {
// Forall(agent, premise → conclusion).simplify
// }
def
invariantNoninterSingleBS
(
spec
:
Spec
)
=
{
def
invariantNoninterSingleBS
(
spec
:
NI
Spec
)
=
{
val
agent
=
spec
.
target
.
params
.
head
// val premise = for ((o, t) <- spec.declass) yield {
...
...
@@ -63,7 +63,7 @@ object InvariantGenerator {
// Forall(agent, Forall(quants, Implies(And.make(premise.map(_._2)), conclusion))).simplify
// }
def
invariantAllEqual
(
spec
:
Spec
)
=
{
def
invariantAllEqual
(
spec
:
NI
Spec
)
=
{
And
.
make
(
for
(
r
<-
spec
.
w
.
sig
.
preds
.
toList
if
r
.
params
.
head
.
typ
==
spec
.
target
.
params
.
head
.
typ
)
yield
{
val
params
=
r
.
params
.
map
(
v
=>
Var
(
v
.
name
+
"t"
,
v
.
typ
))
Forall
(
params
,
genEq
(
r
,
params
))
...
...
src/test/scala/de/tum/workflows/tests/EncodingTest.scala
View file @
2c08691d
...
...
@@ -81,7 +81,7 @@ class EncodingTest extends FlatSpec {
val
choices
=
Set
(
Fun
(
"choice0"
,
List
(
"x"
,
"y"
)))
val
Rab
=
Fun
(
"R"
,
List
(
"a"
,
"b"
))
val
s
=
Spec
(
Workflow
.
EMPTY
,
Map
(),
Rab
,
List
())
val
s
=
NI
Spec
(
Workflow
.
EMPTY
,
Map
(),
Rab
,
List
())
val
nonint
=
Noninterference
(
choices
,
s
)
...
...
@@ -99,7 +99,7 @@ class EncodingTest extends FlatSpec {
choices
should
be
(
Set
(
Fun
(
"choice0"
,
List
(
"x"
,
"s"
))))
val
ce
=
Fun
(
"R"
,
List
(
"ax"
,
"as"
))
val
s
=
Spec
(
Workflow
.
EMPTY
,
Map
(),
ce
,
List
())
val
s
=
NI
Spec
(
Workflow
.
EMPTY
,
Map
(),
ce
,
List
())
val
noninter
=
Noninterference
(
choices
,
s
)
noninter
should
be
(
...
...
@@ -107,7 +107,7 @@ class EncodingTest extends FlatSpec {
Stubborn
(
"ax"
,
choices
),
Finally
(
Exists
(
"as"
,
Neg
(
Equiv
(
ce
.
in
(
T1
),
ce
.
in
(
T2
))))))))
val
s2
=
Spec
(
w
,
Map
(),
Fun
(
"R"
,
List
(
"ax"
,
"as"
)),
List
())
val
s2
=
NI
Spec
(
w
,
Map
(),
Fun
(
"R"
,
List
(
"ax"
,
"as"
)),
List
())
val
prop
=
Properties
.
noninterStubborn
(
s2
)
val
(
agents
,
res
)
=
FOTransformers
.
eliminateExistentials
(
prop
)
...
...
src/test/scala/de/tum/workflows/tests/ParserTest.scala
View file @
2c08691d
...
...
@@ -35,7 +35,7 @@ class ParserTest extends FlatSpec {
}
}
def
testSpecResult
(
s
:
String
,
spec
:
blocks.Spec
)
{