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
56228e9d
Commit
56228e9d
authored
Mar 14, 2017
by
Christian Müller
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
initial looping version
parents
Changes
16
Hide whitespace changes
Inline
Side-by-side
Showing
16 changed files
with
946 additions
and
0 deletions
+946
-0
.gitignore
.gitignore
+24
-0
.project
.project
+14
-0
build.sbt
build.sbt
+14
-0
project/plugins.sbt
project/plugins.sbt
+1
-0
scala/de/tum/workflows/Implicits.scala
scala/de/tum/workflows/Implicits.scala
+10
-0
scala/de/tum/workflows/Main.scala
scala/de/tum/workflows/Main.scala
+19
-0
scala/de/tum/workflows/blocks/Precondition.scala
scala/de/tum/workflows/blocks/Precondition.scala
+96
-0
scala/de/tum/workflows/blocks/Workflow.scala
scala/de/tum/workflows/blocks/Workflow.scala
+27
-0
scala/de/tum/workflows/pqltl/PQLTL.scala
scala/de/tum/workflows/pqltl/PQLTL.scala
+122
-0
scala/de/tum/workflows/pqltl/PQLTLTermfunctions.scala
scala/de/tum/workflows/pqltl/PQLTLTermfunctions.scala
+118
-0
src/main/scala/de/tum/workflows/Implicits.scala
src/main/scala/de/tum/workflows/Implicits.scala
+12
-0
src/main/scala/de/tum/workflows/Main.scala
src/main/scala/de/tum/workflows/Main.scala
+26
-0
src/main/scala/de/tum/workflows/WorkflowEncoding.scala
src/main/scala/de/tum/workflows/WorkflowEncoding.scala
+146
-0
src/main/scala/de/tum/workflows/blocks/Workflow.scala
src/main/scala/de/tum/workflows/blocks/Workflow.scala
+49
-0
src/main/scala/de/tum/workflows/foltl/FOLTL.scala
src/main/scala/de/tum/workflows/foltl/FOLTL.scala
+139
-0
src/main/scala/de/tum/workflows/foltl/FOLTLTermFunctions.scala
...ain/scala/de/tum/workflows/foltl/FOLTLTermFunctions.scala
+129
-0
No files found.
.gitignore
0 → 100644
View file @
56228e9d
*.class
*.log
# sbt specific
.cache
.cache-main
.cache-tests
.history
.lib/
dist/*
target/
lib_managed/
src_managed/
project/boot/
project/plugins/project/
# Scala-IDE specific
.scala_dependencies
.worksheet
# Eclipse
build
.classpath
.settings/
.project
0 → 100644
View file @
56228e9d
<projectDescription>
<name>LoopingWorkflows</name>
<buildSpec>
<buildCommand>
<name>org.scala-ide.sdt.core.scalabuilder</name>
</buildCommand>
</buildSpec>
<natures>
<nature>org.scala-ide.sdt.core.scalanature</nature>
<nature>org.eclipse.jdt.core.javanature</nature>
</natures>
<linkedResources> </linkedResources>
</projectDescription>
\ No newline at end of file
build.sbt
0 → 100644
View file @
56228e9d
name
:=
"LoopingWorkflows"
version
:=
"0.1"
scalaVersion
:=
"2.11.8"
libraryDependencies
++=
Seq
(
"com.typesafe.scala-logging"
%%
"scala-logging"
%
"3.5.0"
,
"ch.qos.logback"
%
"logback-classic"
%
"1.1.7"
,
"org.scalactic"
%%
"scalactic"
%
"3.0.1"
,
"org.scalatest"
%%
"scalatest"
%
"3.0.1"
%
"test"
,
"org.scala-graph"
%%
"graph-core"
%
"1.11.4"
)
project/plugins.sbt
0 → 100644
View file @
56228e9d
addSbtPlugin
(
"com.artima.supersafe"
%
"sbtplugin"
%
"1.1.0"
)
scala/de/tum/workflows/Implicits.scala
0 → 100644
View file @
56228e9d
package
de.tum.workflows
import
pqltl.PQLTL._
object
Implicits
{
implicit
def
toList
[
A
](
v
:
A
)
:
List
[
A
]
=
List
(
v
)
// Logic
implicit
def
nameToVar
(
name
:
String
)
=
Var
(
name
)
}
scala/de/tum/workflows/Main.scala
0 → 100644
View file @
56228e9d
package
de.tum.workflows
import
pqltl.PQLTL._
import
blocks.WorkFlow._
import
Implicits._
object
Main
extends
App
{
// val post = Historically(Forall(List("x", "p"), Neg(And(Fun("Conf", List("x", "p")), Fun("Know", List("x", "p"))))))
//
// val workflow = Workflow(List(
// ForallMayBlock(List("a1", "p1"), Add(True, "Conf", List("a1", "p1"))),
// ForallMayBlock(List("a2", "b2", "p2"), Add(Fun("Conf", List("b2", "p2")), "Know", List("a2", "p2")))
// ))
// println(Neg(post).simplify())
// println(workflow)
}
\ No newline at end of file
scala/de/tum/workflows/blocks/Precondition.scala
0 → 100644
View file @
56228e9d
package
de.tum.workflows.blocks
import
de.tum.workflows.pqltl.PQLTL._
import
de.tum.workflows.blocks.WorkFlow._
import
com.typesafe.scalalogging.LazyLogging
object
Precondition
extends
LazyLogging
{
// Generates new name everytime
def
auxname
=
"Aux"
def
apply
(
w
:
Workflow
,
t
:
Term
)
:
Term
=
{
val
simp
=
t
.
simplify
()
val
result
=
foldblocks
(
simp
,
w
.
steps
)
val
notemporals
=
result
.
removeTemporals
()
notemporals
.
simplify
()
}
def
foldblocks
(
t
:
Term
,
steps
:
List
[
Block
])
:
Term
=
{
steps
.
zipWithIndex
.
foldRight
(
t
)((
b
,
t
)
=>
b
match
{
case
(
ForallBlock
(
agents
,
stmts
),
_
)
=>
foldstmts
(
t
,
stmts
)
case
(
ForallMayBlock
(
agents
,
stmts
),
i
)
=>
foldmaystmts
(
t
,
auxname
+
i
,
stmts
)
})
}
def
foldstmts
(
t
:
Term
,
steps
:
List
[
Statement
])
:
Term
=
{
// No aux calls
steps
.
foldRight
(
t
)(
wp
(
xs
=>
True
)
_
).
simplify
()
}
def
foldmaystmts
(
t
:
Term
,
auxname
:
String
,
steps
:
List
[
Statement
])
:
Term
=
{
steps
.
foldRight
(
t
)(
wp
(
xs
=>
Fun
(
auxname
,
None
,
xs
))
_
).
simplify
()
}
def
wp
(
mkaux
:
List
[
Var
]
=>
Term
)(
step
:
Statement
,
t
:
Term
)
:
Term
=
{
// Resolve temporals
val
unwrapped
=
t
.
everywhere
({
case
Since
(
u
,
v
)
=>
Or
(
v
,
And
(
u
,
Since
(
u
,
v
)))
case
Once
(
t
)
=>
Or
(
t
,
Once
(
t
))
case
Historically
(
t
)
=>
And
(
t
,
Historically
(
t
))
})
val
simp
=
unwrapped
.
simplify
()
val
replaced
=
(
step
match
{
case
Add
(
guard
,
fun
,
tuple
)
=>
simp
.
everywhere
({
// Ignore temporals
case
_:
TemporalTerm
=>
t
case
Fun
(
name
,
Some
(
ind
),
xs
)
if
fun
==
name
=>
Or
(
Fun
(
name
,
Some
(
ind
),
xs
),
Exists
((
guard
.
freeVars
()
--
xs
).
toList
,
And
(
guard
.
annotate
(
ind
),
mkaux
(
xs
).
annotate
(
ind
)))
)
case
Fun
(
name
,
None
,
xs
)
=>
{
println
(
"FAIL"
)
False
}
})
case
Remove
(
guard
,
fun
,
tuple
)
=>
simp
.
everywhere
({
// Ignore temporals
case
_:
TemporalTerm
=>
t
case
Fun
(
name
,
Some
(
ind
),
xs
)
if
fun
==
name
=>
And
(
Fun
(
name
,
Some
(
ind
),
xs
),
Forall
((
guard
.
freeVars
()
--
xs
).
toList
,
Or
(
Neg
(
guard
.
annotate
(
ind
)),
Neg
(
mkaux
(
xs
).
annotate
(
ind
))))
)
case
Fun
(
name
,
None
,
xs
)
=>
{
println
(
"FAIL"
)
False
}
})
})
val
pre
=
replaced
.
simplify
()
// Unwrap prev
val
result
=
pre
.
everywhere
({
case
Previously
(
t
)
=>
t
})
logger
.
debug
(
s
"Precondition of $t under $step is $result"
)
result
}
}
scala/de/tum/workflows/blocks/Workflow.scala
0 → 100644
View file @
56228e9d
package
de.tum.workflows.blocks
import
de.tum.workflows.pqltl.PQLTL._
object
WorkFlow
{
case
class
Workflow
(
steps
:
List
[
Block
])
{
override
def
toString
()
=
steps
.
mkString
(
"\n"
)
}
abstract
sealed
class
Block
abstract
class
Statement
case
class
Add
(
guard
:
Term
,
fun
:
String
,
tuple
:
List
[
Var
])
extends
Statement
{
override
def
toString
()
=
guard
+
" → "
+
fun
+
" += "
+
tuple
.
mkString
(
"("
,
","
,
")"
)
}
case
class
Remove
(
guard
:
Term
,
fun
:
String
,
tuple
:
List
[
Var
])
extends
Statement
{
override
def
toString
()
=
guard
+
" → "
+
fun
+
" -= "
+
tuple
.
mkString
(
"("
,
","
,
")"
)
}
case
class
ForallBlock
(
agents
:
List
[
Var
],
steps
:
List
[
Statement
])
extends
Block
{
override
def
toString
()
=
"forall "
+
agents
.
mkString
(
","
)
+
steps
.
mkString
(
"\n "
,
";\n "
,
""
)
}
case
class
ForallMayBlock
(
agents
:
List
[
Var
],
steps
:
List
[
Statement
])
extends
Block
{
override
def
toString
()
=
"forall "
+
agents
.
mkString
(
","
)
+
" may"
+
steps
.
mkString
(
"\n "
,
";\n "
,
""
)
}
}
\ No newline at end of file
scala/de/tum/workflows/pqltl/PQLTL.scala
0 → 100644
View file @
56228e9d
package
de.tum.workflows.pqltl
object
PQLTL
{
abstract
class
Term
{
def
simplify
()
=
TermFunctions
.
simplify
(
this
)
def
freeVars
()
=
TermFunctions
.
freeVars
(
this
)
def
removeTemporals
()
=
TermFunctions
.
removeTemporals
(
this
)
def
everywhere
(
trans
:
PartialFunction
[
Term
,
Term
])
=
TermFunctions
.
everywhere
(
trans
,
this
)
def
assumeEmpty
(
name
:
String
)
=
TermFunctions
.
assumeEmpty
(
this
,
name
)
def
annotate
(
name
:
String
)
=
TermFunctions
.
annotate
(
this
,
name
)
def
bracketed
()
:
String
=
this
match
{
case
_:
BinOp
=>
"("
+
this
+
")"
case
_
=>
this
.
toString
()
}
}
case
object
True
extends
Term
case
object
False
extends
Term
case
class
Var
(
name
:
String
)
extends
Term
{
override
def
toString
()
=
name
}
object
Fun
{
def
apply
(
name
:
String
,
params
:
List
[
Var
])
:
Fun
=
Fun
(
name
,
None
,
params
)
}
case
class
Fun
(
name
:
String
,
ind
:
Option
[
String
],
params
:
List
[
Var
])
extends
Term
{
override
def
toString
()
=
name
+
ind
.
mkString
(
"("
,
","
,
")"
)
+
params
.
mkString
(
"("
,
","
,
")"
)
}
trait
Quantifier
extends
Term
{
def
qmake
:
(
List
[
Var
],
Term
)
=>
Quantifier
def
qname
:
String
def
vars
:
List
[
Var
]
def
t
:
Term
override
def
toString
()
=
{
qname
+
" "
+
vars
.
mkString
(
","
)
+
". "
+
t
.
bracketed
()
}
}
object
Quantifier
{
def
unapply
(
q
:
Quantifier
)
=
Some
((
q
.
qmake
,
q
.
vars
,
q
.
t
))
}
case
class
Exists
(
vars
:
List
[
Var
],
t
:
Term
)
extends
Quantifier
{
val
qname
=
"∃"
val
qmake
=
Exists
.
apply
_
}
case
class
Forall
(
vars
:
List
[
Var
],
t
:
Term
)
extends
Quantifier
{
val
qname
=
"∀"
val
qmake
=
Forall
.
apply
_
}
trait
TemporalTerm
extends
Term
case
class
Previously
(
t
:
Term
)
extends
TemporalTerm
{
override
def
toString
()
=
{
"Prev "
+
t
.
bracketed
()
}
}
case
class
Historically
(
t
:
Term
)
extends
TemporalTerm
{
override
def
toString
()
=
{
"A "
+
t
.
bracketed
()
}
}
case
class
Since
(
t1
:
Term
,
t2
:
Term
)
extends
TemporalTerm
{
override
def
toString
()
=
{
t1
.
bracketed
()
+
" S "
+
t2
.
bracketed
()
}
}
case
class
Once
(
t
:
Term
)
extends
TemporalTerm
trait
BinOp
extends
Term
{
def
make
:
(
Term
,
Term
)
=>
BinOp
def
opname
:
String
def
t1
:
Term
def
t2
:
Term
override
def
toString
()
=
{
(
t1
,
t2
)
match
{
case
(
t1
:
BinOp
,
t2
:
BinOp
)
if
(
opname
==
t1
.
opname
==
t2
.
opname
)
=>
t1
+
" "
+
opname
+
" "
+
t2
case
(
t1
:
BinOp
,
_
)
if
(
opname
==
t1
.
opname
)
=>
t1
+
" "
+
opname
+
" "
+
t2
.
bracketed
()
case
(
_
,
t2
:
BinOp
)
if
(
opname
==
t2
.
opname
)
=>
t1
.
bracketed
()
+
" "
+
opname
+
" "
+
t2
case
_
=>
t1
.
bracketed
()
+
" "
+
opname
+
" "
+
t2
.
bracketed
()
}
}
}
object
BinOp
{
def
unapply
(
binop
:
BinOp
)
=
{
Some
((
binop
.
make
,
binop
.
t1
,
binop
.
t2
))
}
}
case
class
Or
(
t1
:
Term
,
t2
:
Term
)
extends
BinOp
{
val
opname
=
"∨"
val
make
=
Or
.
apply
_
}
case
class
And
(
t1
:
Term
,
t2
:
Term
)
extends
BinOp
{
val
opname
=
"∧"
val
make
=
And
.
apply
_
}
case
class
Eq
(
t1
:
Term
,
t2
:
Term
)
extends
BinOp
{
val
opname
=
"↔"
val
make
=
Eq
.
apply
_
}
trait
UnOp
extends
Term
{
def
opname
:
String
def
t
:
Term
override
def
toString
()
=
opname
+
t
.
bracketed
}
case
class
Neg
(
t
:
Term
)
extends
UnOp
{
val
opname
=
"¬"
}
}
\ No newline at end of file
scala/de/tum/workflows/pqltl/PQLTLTermfunctions.scala
0 → 100644
View file @
56228e9d
package
de.tum.workflows.pqltl
import
PQLTL._
object
TermFunctions
{
def
freeVars
(
t
:
Term
)
=
{
def
free
(
t
:
Term
,
bound
:
Set
[
Var
])
:
Set
[
Var
]
=
{
t
match
{
// Extractors
// Exists, Forall
case
Quantifier
(
_
,
ps
,
t
)
=>
free
(
t
,
bound
++
ps
)
case
Since
(
t1
,
t2
)
=>
free
(
t1
,
bound
)
++
free
(
t2
,
bound
)
case
Once
(
t1
)
=>
free
(
t1
,
bound
)
case
Historically
(
t1
)
=>
free
(
t1
,
bound
)
// And, Or, Eq
case
BinOp
(
_
,
t1
,
t2
)
=>
free
(
t1
,
bound
)
++
free
(
t2
,
bound
)
case
Neg
(
t1
)
=>
free
(
t1
,
bound
)
case
Fun
(
_
,
Some
(
ind
),
ps
)
=>
(
ps
.
toSet
--
bound
)
+
Var
(
ind
)
case
Fun
(
_
,
_
,
ps
)
=>
(
ps
.
toSet
--
bound
)
case
v
:
Var
if
!bound
(
v
)
=>
Set
(
v
)
case
x
=>
Set
()
}
}
free
(
t
,
Set
())
}
def
simplify
(
t
:
Term
)
:
Term
=
{
val
simp
:
PartialFunction
[
Term
,
Term
]
=
{
// Push negation inward
case
Neg
(
Or
(
t1
,
t2
))
=>
And
(
Neg
(
t1
),
Neg
(
t2
))
case
Neg
(
And
(
t1
,
t2
))
=>
Or
(
Neg
(
t1
),
Neg
(
t2
))
case
Neg
(
Historically
(
t
))
=>
Once
(
Neg
(
t
))
case
Neg
(
Once
(
t
))
=>
Historically
(
Neg
(
t
))
case
Neg
(
Previously
(
t
))
=>
Previously
(
Neg
(
t
))
case
Neg
(
Forall
(
vars
,
t
))
=>
Exists
(
vars
,
Neg
(
t
))
case
Neg
(
Exists
(
vars
,
t
))
=>
Forall
(
vars
,
Neg
(
t
))
// Simple laws
case
Neg
(
True
)
=>
False
case
Neg
(
False
)
=>
True
case
Or
(
True
,
t
)
=>
True
case
Or
(
t
,
True
)
=>
True
case
Or
(
False
,
t
)
=>
t
case
Or
(
t
,
False
)
=>
t
case
And
(
False
,
t
)
=>
False
case
And
(
t
,
False
)
=>
False
case
And
(
True
,
t
)
=>
t
case
And
(
t
,
True
)
=>
t
case
Eq
(
False
,
False
)
=>
True
case
Neg
(
Neg
(
t
))
=>
t
// TODO: Since
// Remove quantifiers if empty
case
Quantifier
(
qmake
,
xs
,
t
)
if
xs
.
isEmpty
=>
t
case
Quantifier
(
qmake
,
xs
,
True
)
=>
True
case
Quantifier
(
qmake
,
xs
,
False
)
=>
False
// Remove variables from quantifiers if not used in the body
// case Quantifier(qmake, xs, t) if !(xs.toSet -- t.freeVars()).isEmpty =>
// qmake((xs.toSet.intersect(t.freeVars())).toList, t)
//
// // Split off binops from quantifiers
// case Quantifier(qmake, xs, BinOp(make, t1, t2)) if (t1.freeVars().intersect(xs.toSet)).isEmpty =>
// make(t1, qmake(xs, t2))
// case Quantifier(qmake, xs, BinOp(make, t1, t2)) if (t2.freeVars().intersect(xs.toSet)).isEmpty =>
// make(qmake(xs, t1), t2)
}
val
t1
=
everywhere
(
simp
,
t
)
if
(
t
==
t1
)
t1
else
simplify
(
t1
)
}
def
everywhere
(
trans
:
PartialFunction
[
Term
,
Term
],
t
:
Term
)
:
Term
=
{
if
(
trans
.
isDefinedAt
(
t
))
trans
(
t
)
else
t
match
{
// Extractors
case
Quantifier
(
make
,
ps
,
t
)
=>
make
(
ps
,
everywhere
(
trans
,
t
))
case
Since
(
t1
,
t2
)
=>
Since
(
everywhere
(
trans
,
t1
),
everywhere
(
trans
,
t2
))
case
Once
(
t1
)
=>
Once
(
everywhere
(
trans
,
t1
))
case
Historically
(
t1
)
=>
Historically
(
everywhere
(
trans
,
t1
))
case
Previously
(
t1
)
=>
Previously
(
everywhere
(
trans
,
t1
))
case
BinOp
(
make
,
t1
,
t2
)
=>
make
(
everywhere
(
trans
,
t1
),
everywhere
(
trans
,
t2
))
case
Neg
(
t1
)
=>
Neg
(
everywhere
(
trans
,
t1
))
case
x
=>
x
}
}
def
removeTemporals
(
t
:
Term
)
:
Term
=
{
t
.
everywhere
({
case
Historically
(
u
)
=>
u
case
Since
(
u
,
v
)
=>
v
case
Once
(
u
)
=>
u
case
_:
TemporalTerm
=>
False
})
}
def
assumeEmpty
(
t
:
Term
,
name
:
String
)
=
{
t
.
everywhere
({
case
Fun
(
f
,
_
,
_
)
if
f
==
name
=>
False
})
}
def
annotate
(
t
:
Term
,
name
:
String
)
=
{
t
.
everywhere
({
case
Fun
(
f
,
None
,
xs
)
=>
Fun
(
f
,
Some
(
name
),
xs
)
})
}
}
\ No newline at end of file
src/main/scala/de/tum/workflows/Implicits.scala
0 → 100644
View file @
56228e9d
package
de.tum.workflows
import
de.tum.workflows.foltl.FOLTL._
object
Implicits
{
implicit
def
toList
[
A
](
v
:
A
)
:
List
[
A
]
=
List
(
v
)
// Logic
implicit
def
nameToVar
(
name
:
String
)
=
Var
(
name
)
implicit
def
nameToVarList
(
name
:
String
)
=
List
(
Var
(
name
))
}
src/main/scala/de/tum/workflows/Main.scala
0 → 100644
View file @
56228e9d
package
de.tum.workflows
import
foltl.FOLTL._
import
blocks.WorkFlow._
import
Implicits._
object
Main
extends
App
{
val
w
=
Workflow
(
List
(
ForallMayBlock
(
List
(
"x"
,
"s"
),
Add
(
Fun
(
"O"
,
"s"
),
"Q"
,
List
(
"x"
,
"s"
))
),
Loop
(
List
(
ForallMayBlock
(
List
(
"x"
,
"y"
,
"s"
),
Add
(
Fun
(
"R"
,
List
(
"y"
,
"s"
)),
"S"
,
List
(
"x"
,
"y"
,
"s"
))
),
ForallBlock
(
List
(
"x"
,
"s"
),
Add
(
Fun
(
"Q"
,
List
(
"x"
,
"s"
)),
"R"
,
List
(
"x"
,
"s"
))
)
))
))
println
(
w
)
val
res
=
Encoding
.
toFOLTL
(
w
)
}
\ No newline at end of file
src/main/scala/de/tum/workflows/WorkflowEncoding.scala
0 → 100644
View file @
56228e9d
package
de.tum.workflows
import
scalax.collection.Graph
// or scalax.collection.mutable.Graph
import
scalax.collection.GraphPredef._
import
scalax.collection.GraphEdge._
import
scalax.collection.edge.LDiEdge
// labeled directed edge
import
scalax.collection.edge.Implicits._
// shortcuts
import
blocks.WorkFlow._
import
de.tum.workflows.foltl.FOLTL
import
de.tum.workflows.foltl.FOLTL._
import
de.tum.workflows.foltl.TermFunctions._
import
scalax.collection.edge.LBase.LEdgeImplicits
object
BlockImplicit
extends
LEdgeImplicits
[
SimpleBlock
];
import
BlockImplicit._
object
Encoding
{
// Naming
// TODO: make sure there are no clashes
def
nodeVar
(
n
:
Any
)
=
Var
(
"n"
+
n
)
def
choiceVar
(
n
:
Any
)
=
"choice"
+
n
def
makeblock
(
b
:
Block
,
n1
:
Int
,
n2
:
Int
,
makeNode
:
(()
=>
Int
),
makeId
:
(()
=>
Block
))
:
(
List
[
LDiEdge
[
Int
]])
=
{
b
match
{
case
Loop
(
steps
)
=>
{
// add empty statement if loop ends with loop
val
adjsteps
=
steps
.
last
match
{
case
_:
Loop
=>
steps
:+
makeId
()
case
_:
Block
=>
steps
}
// looping with n-1 nodes around n1
val
newnodes
=
n1
+:
(
0
until
adjsteps
.
size
-
1
).
toList
.
map
(
_
=>
makeNode
())
:+
n1
// n1 -> n2, n2 -> n3, ...
val
edgenodes
=
newnodes
.
sliding
(
2
).
toList
val
edges
=
for
((
step
,
List
(
start
,
end
))
<-
adjsteps
.
zip
(
edgenodes
))
yield
{
makeblock
(
step
,
start
,
end
,
makeNode
,
makeId
)
}
edges
.
flatten
:+
(
n1
~+>
n2
)(
makeId
())
}
// single edge
case
b
:
Block
=>
{
List
((
n1
~+>
n2
)(
b
))
}
}
}
def
toGraph
(
w
:
Workflow
)
=
{
var
n1
=
0
;
def
newnode
()
=
{
n1
=
n1
+
1
n1
}
def
makeid
()
=
ForallBlock
(
List
(),
List
())
val
edges
=
(
for
((
step
,
i
)
<-
w
.
steps
.
zipWithIndex
)
yield
{
if
(
i
==
w
.
steps
.
size
-
1
)
{
val
n
=
n1
val
n2
=
newnode
()
val
edges
=
makeblock
(
step
,
n
,
n2
,
newnode
,
makeid
)
edges
:+
(
n2
~+>
n2
)(
makeid
())
}
else
{
makeblock
(
step
,
n1
,
newnode
(),
newnode
,
makeid
)
}
}).
flatten
var
nodes
=
(
0
until
n1
).
toList
Graph
.
from
(
nodes
,
edges
)
}
def
encodeGraph
(
g
:
Graph
[
Int
,
LDiEdge
])
=
{
val
allnodes
=
for
(
n
<-
g
.
nodes
.
toList
)
yield
{
// TODO: better syntax
val
list
=
n
.
outgoing
.
toList
.
map
(
e
=>
nodeVar
(
e
.
to
))
Implies
(
nodeVar
(
n
),
Next
(
BinOp
.
makeL
(
Or
.
apply
,
list
)))
}
Globally
(
BinOp
.
makeL
(
And
.
apply
,
allnodes
))
}
def
encodeSanity
(
g
:
Graph
[
Int
,
LDiEdge
])
=
{
val
negs
=
for
(
n
<-
g
.
nodes
.
toList
;
n2
<-
g
.
nodes
.
toList
if
n
<
n2
)
yield
{
Neg
(
And
(
nodeVar
(
n
),
nodeVar
(
n2
)))
}
Globally
(
BinOp
.
makeL
(
And
.
apply
,
negs
))
}
def
encodeStmt
(
s
:
Statement
,
pred
:
Option
[
Term
])
:
(
Term
,
String
)
=
{
var
guard
=
s
.
guard
for
(
p
<-
pred
)
{
// if pred defined
guard
=
And
(
guard
,
p
)
}
val
t
=
s
match
{
case
Add
(
_
,
f
,
tup
)
=>
Or
(
Fun
(
f
,
tup
),
guard
)
case
Remove
(
_
,
f
,
tup
)
=>
And
(
Fun
(
f
,
tup
),
Neg
(
guard
))
}
(
Forall
(
s
.
tuple
,
Eq
(
Next
(
Fun
(
s
.
fun
,
s
.
tuple
)),
t
)),
s
.
fun
)
}
def
encodeSem
(
g
:
Graph
[
Int
,
LDiEdge
])
=
{
// TODO: this is still wrong - should be EVERY relation
// all relations that are updated
// val updated = for (e <- g.edges.toList; s <- e.steps) yield {
// // e has a block that is not a loop
// s.fun
// }
val
impls
=
for
(
e
<-
g
.
edges
.
toList
)
yield
{
val
choice
=
if
(
e
.
may
)
Some
(
Fun
(
choiceVar
(
e
.
from
),
e
.
label
.
agents
))
else
None
val
res
=
for
(
s
<-
e
.
steps
)
yield
{
encodeStmt
(
s
,
choice
)
}
// TODO fix this
// val updates = res.map(_._2)
// val staying:List[Term] = for (u <- updated if !updates.contains(u)) yield {
//
// }
val
terms
=
res
.
map
(
_
.
_1
)
Implies
(
And
(
nodeVar
(
e
.
from
),
Next
(
nodeVar
(
e
.
to
))),
BinOp
.
makeL
(
And
.
apply
,
terms
))
}
BinOp
.
makeL
(
And
.
apply
,
impls
)
}
def
toFOLTL
(
w
:
Workflow
)
=
{
val
g
=
toGraph
(
w
)
println
(
"Graph of w: "
+
g
)
val
cfg
=
encodeGraph
(
g
)
println
(
"cfg(w): "
+
cfg
)
val
sanity
=
encodeSanity
(
g
)
println
(
"sanity(w): "
+
sanity
)
// val encodesem = encodeSem(g)
}
}
\ No newline at end of file
src/main/scala/de/tum/workflows/blocks/Workflow.scala
0 → 100644
View file @
56228e9d
package
de.tum.workflows.blocks
import
de.tum.workflows.foltl.FOLTL._
object
WorkFlow
{
case
class
Workflow
(
steps
:
List
[
Block
])
{
override
def
toString
()
=
steps
.
mkString
(
"\n"
)
}
abstract
sealed
class
Block
abstract
sealed
class
SimpleBlock
extends
Block
{
def
agents
:
List
[
Var
]
def
steps
:
List
[
Statement
]
def
may
:
Boolean
}
abstract
class
Statement
{
def
guard
:
Term
def
fun
:
String
def
tuple
:
List
[
Var
]
}
case
class
Add
(
guard
:
Term
,
fun
:
String
,
tuple
:
List
[
Var
])
extends
Statement
{
override
def
toString
()
=
guard
+
" → "
+
fun
+
" += "
+
tuple
.
mkString
(
"("
,
","
,
")"
)
}
case
class
Remove
(
guard
:
Term
,
fun
:
String
,
tuple
:
List
[
Var
])
extends
Statement
{
override
def
toString
()
=
guard
+
" → "
+
fun
+
" -= "
+
tuple
.
mkString
(
"("
,
","
,
")"
)
}
case
class
ForallBlock
(
agents
:
List
[
Var
],
steps
:
List
[
Statement
])
extends
SimpleBlock
{
val
may
=
false
override
def
toString
()
=
"forall "
+
agents
.
mkString
(
","
)
+
steps
.
mkString
(
"\n "
,
";\n "
,
""
)
}
case
class
ForallMayBlock
(
agents
:
List
[
Var
],
steps
:
List
[
Statement
])
extends
SimpleBlock
{
val
may
=
true
override
def
toString
()
=
"forall "
+
agents
.
mkString
(
","
)
+
" may"
+
steps
.
mkString
(
"\n "
,
";\n "
,
""
)
}
case
class
Loop
(
steps
:
List
[
Block
])
extends
Block
{
val
agents
=
List
()
override
def
toString
()
=
{
// indentation
val
s
=
steps
.
map
(
_
.
toString
().
lines
.
mkString
(
" "
,
"\n "
,
""
))
"loop(*)\n"
+
s
.
mkString
(
";\n"
)
}
}
}
\ No newline at end of file
src/main/scala/de/tum/workflows/foltl/FOLTL.scala
0 → 100644
View file @
56228e9d
package
de.tum.workflows.foltl
//import de.tum.workflows.foltl.TermFunctions._