Commit 4466e442 authored by Eugen Zalinescu's avatar Eugen Zalinescu
Browse files

works for Globally; Term -> Formula

parent e59e0ae8
...@@ -9,7 +9,7 @@ import scalax.collection.edge.Implicits._ // shortcuts ...@@ -9,7 +9,7 @@ import scalax.collection.edge.Implicits._ // shortcuts
import blocks._ import blocks._
import de.tum.workflows.foltl.FOLTL import de.tum.workflows.foltl.FOLTL
import de.tum.workflows.foltl.FOLTL._ import de.tum.workflows.foltl.FOLTL._
import de.tum.workflows.foltl.TermFunctions._ import de.tum.workflows.foltl.FormulaFunctions._
import com.typesafe.scalalogging._ import com.typesafe.scalalogging._
...@@ -113,7 +113,7 @@ object Encoding extends LazyLogging { ...@@ -113,7 +113,7 @@ object Encoding extends LazyLogging {
And.make(nodeVar(0), And.make(nodes), Globally(And.make(negs))) And.make(nodeVar(0), And.make(nodes), Globally(And.make(negs)))
} }
def encodeStmt(s: Statement, pred: Option[Term], bind: List[Var]): (Term, String) = { def encodeStmt(s: Statement, pred: Option[Formula], bind: List[Var]): (Formula, String) = {
// var guard = s.guard // var guard = s.guard
// for (p <- pred) { // if pred defined // for (p <- pred) { // if pred defined
// guard = And(guard, p) // guard = And(guard, p)
......
...@@ -12,7 +12,7 @@ import java.io.PrintWriter ...@@ -12,7 +12,7 @@ import java.io.PrintWriter
import java.io.File import java.io.File
import de.tum.workflows.blocks.Workflow import de.tum.workflows.blocks.Workflow
import de.tum.workflows.blocks.Spec import de.tum.workflows.blocks.Spec
import de.tum.workflows.foltl.TermFunctions import de.tum.workflows.foltl.FormulaFunctions
object Main extends App with LazyLogging { object Main extends App with LazyLogging {
...@@ -40,14 +40,14 @@ object Main extends App with LazyLogging { ...@@ -40,14 +40,14 @@ object Main extends App with LazyLogging {
writer.close() writer.close()
} }
def writeExample(name: String, spec:Spec, prop: Term) { def writeExample(name: String, spec:Spec, prop: Formula) {
var metrics = List[String]() var metrics = List[String]()
write(s"${name}.foltl", prop.pretty()) write(s"${name}.foltl", prop.pretty())
metrics :+= s"${name}.foltl: ${prop.opsize()}" metrics :+= s"${name}.foltl: ${prop.opsize()}"
if (!TermFunctions.checkSanity(prop)) { if (!FormulaFunctions.checkSanity(prop)) {
logger.error("Property didn't pass sanity check") logger.error("Property didn't pass sanity check")
return return
} }
......
...@@ -135,7 +135,7 @@ object WorkflowParser extends RegexParsers with LazyLogging { ...@@ -135,7 +135,7 @@ object WorkflowParser extends RegexParsers with LazyLogging {
def FUN = VAR ~ TUPLE ^^ { case f ~ tup => Fun(f.name, tup) } def FUN = VAR ~ TUPLE ^^ { case f ~ tup => Fun(f.name, tup) }
def SIMPLETERM = (tt | ff | FUN ) def SIMPLETERM = (tt | ff | FUN )
def TERM:Parser[Term] = (SIMPLETERM | GLOBALLY | FINALLY | AND | OR | NEG ) def TERM:Parser[Formula] = (SIMPLETERM | GLOBALLY | FINALLY | AND | OR | NEG )
def ADD = TERM ~ ("→" | "->") ~ VAR ~ "+=" ~ TUPLE ^^ { case guard ~ _ ~ fun ~ _ ~ tup => Add(guard, fun.name, tup) } def ADD = TERM ~ ("→" | "->") ~ VAR ~ "+=" ~ TUPLE ^^ { case guard ~ _ ~ fun ~ _ ~ tup => Add(guard, fun.name, tup) }
def REM = TERM ~ ("→" | "->") ~ VAR ~ "-=" ~ TUPLE ^^ { case guard ~ _ ~ fun ~ _ ~ tup => Remove(guard, fun.name, tup) } def REM = TERM ~ ("→" | "->") ~ VAR ~ "-=" ~ TUPLE ^^ { case guard ~ _ ~ fun ~ _ ~ tup => Remove(guard, fun.name, tup) }
......
...@@ -19,7 +19,7 @@ object Workflow { ...@@ -19,7 +19,7 @@ object Workflow {
val EMPTY = Workflow(Signature.EMPTY, List()) val EMPTY = Workflow(Signature.EMPTY, List())
} }
case class Spec(w: Workflow, declass: List[(Fun, Term)], target: Fun, causals:List[Var]) extends LazyLogging { case class Spec(w: Workflow, declass: List[(Fun, Formula)], target: Fun, causals:List[Var]) extends LazyLogging {
override def toString = { override def toString = {
s"Spec\nWorkflow:\n$w\nDeclass:$declass\nTarget:$target" s"Spec\nWorkflow:\n$w\nDeclass:$declass\nTarget:$target"
} }
...@@ -62,17 +62,17 @@ abstract sealed class SimpleBlock extends Block { ...@@ -62,17 +62,17 @@ abstract sealed class SimpleBlock extends Block {
} }
abstract class Statement { abstract class Statement {
def guard: Term def guard: Formula
def fun: String def fun: String
def tuple: List[Var] def tuple: List[Var]
def freeVars() = guard.freeVars() ++ tuple def freeVars() = guard.freeVars() ++ tuple
} }
case class Add(guard: Term, fun: String, tuple: List[Var]) extends Statement { case class Add(guard: Formula, fun: String, tuple: List[Var]) extends Statement {
override def toString() = guard + " → " + fun + " += " + tuple.mkString("(", ",", ")") + ";" override def toString() = guard + " → " + fun + " += " + tuple.mkString("(", ",", ")") + ";"
} }
case class Remove(guard: Term, fun: String, tuple: List[Var]) extends Statement { case class Remove(guard: Formula, fun: String, tuple: List[Var]) extends Statement {
override def toString() = guard + " → " + fun + " -= " + tuple.mkString("(", ",", ")") + ";" override def toString() = guard + " → " + fun + " -= " + tuple.mkString("(", ",", ")") + ";"
} }
......
...@@ -6,15 +6,15 @@ import scala.annotation.tailrec ...@@ -6,15 +6,15 @@ import scala.annotation.tailrec
//import de.tum.workflows.foltl.TermFunctions._ //import de.tum.workflows.foltl.TermFunctions._
object FOLTL { object FOLTL {
abstract class Term { abstract class Formula {
def simplify() = TermFunctions.simplify(this) def simplify() = FormulaFunctions.simplify(this)
def freeVars() = TermFunctions.freeVars(this) def freeVars() = FormulaFunctions.freeVars(this)
def everywhere(trans: PartialFunction[Term, Term]) = TermFunctions.everywhere(trans, this) def everywhere(trans: PartialFunction[Formula, Formula]) = FormulaFunctions.everywhere(trans, this)
def assumeEmpty(name: String) = TermFunctions.assumeEmpty(this, name) def assumeEmpty(name: String) = FormulaFunctions.assumeEmpty(this, name)
def in(name: String) = TermFunctions.annotate(this, name) def in(name: String) = FormulaFunctions.annotate(this, name)
def in(name: String, ignore: Set[String]) = TermFunctions.annotate(this, name, ignore) def in(name: String, ignore: Set[String]) = FormulaFunctions.annotate(this, name, ignore)
def collect[T](coll: PartialFunction[Term, List[T]]) = TermFunctions.collect(coll, this) def collect[T](coll: PartialFunction[Formula, List[T]]) = FormulaFunctions.collect(coll, this)
def opsize() = TermFunctions.opsize(this) def opsize() = FormulaFunctions.opsize(this)
def bracketed(): String = this match { def bracketed(): String = this match {
case _: BinOp => "(" + this + ")" case _: BinOp => "(" + this + ")"
...@@ -40,13 +40,13 @@ object FOLTL { ...@@ -40,13 +40,13 @@ object FOLTL {
} }
} }
case object True extends Term case object True extends Formula
case object False extends Term case object False extends Formula
object Var { object Var {
val DEFAULT_TYPE = "T" val DEFAULT_TYPE = "T"
} }
case class Var(name: String, typ:String = Var.DEFAULT_TYPE) extends Term { case class Var(name: String, typ:String = Var.DEFAULT_TYPE) extends Formula {
override def toString() = s"$name" override def toString() = s"$name"
def withType() = s"$name:$typ" def withType() = s"$name:$typ"
} }
...@@ -54,17 +54,17 @@ object FOLTL { ...@@ -54,17 +54,17 @@ object FOLTL {
object Fun { object Fun {
def apply(name: String, params: List[Var]): Fun = Fun(name, None, params) 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 { case class Fun(name: String, ind: Option[String], params: List[Var]) extends Formula {
override def toString() = name + Utils.mkString(ind, "(", "", ")") + params.map(_.name).mkString("(", ",", ")") override def toString() = name + Utils.mkString(ind, "(", "", ")") + params.map(_.name).mkString("(", ",", ")")
def updatedParams(index: Int, p:Var) = Fun(name, ind, params.updated(index, p)) def updatedParams(index: Int, p:Var) = Fun(name, ind, params.updated(index, p))
def updatedParams(list: List[Var]) = Fun(name, ind, list) def updatedParams(list: List[Var]) = Fun(name, ind, list)
} }
trait Quantifier extends Term { trait Quantifier extends Formula {
def qmake: (List[Var], Term) => Quantifier def qmake: (List[Var], Formula) => Quantifier
def qname: String def qname: String
def vars: List[Var] def vars: List[Var]
def t: Term def t: Formula
override def toString() = { override def toString() = {
// show types only in quantifiers // show types only in quantifiers
...@@ -76,51 +76,51 @@ object FOLTL { ...@@ -76,51 +76,51 @@ object FOLTL {
def unapply(q: Quantifier) = Some((q.qmake, q.vars, q.t)) def unapply(q: Quantifier) = Some((q.qmake, q.vars, q.t))
} }
case class Exists(vars: List[Var], t: Term) extends Quantifier { case class Exists(vars: List[Var], t: Formula) extends Quantifier {
val qname = "∃" val qname = "∃"
val qmake = Exists.apply _ val qmake = Exists.apply _
} }
case class Forall(vars: List[Var], t: Term) extends Quantifier { case class Forall(vars: List[Var], t: Formula) extends Quantifier {
val qname = "∀" val qname = "∀"
val qmake = Forall.apply _ val qmake = Forall.apply _
} }
case class ForallOtherThan(vars: List[Var], otherthan:List[Var], t: Term) extends Quantifier { case class ForallOtherThan(vars: List[Var], otherthan:List[Var], t: Formula) extends Quantifier {
val qname = "∀" val qname = "∀"
val qmake = ForallOtherThan.apply(_:List[Var], otherthan, _:Term) val qmake = ForallOtherThan.apply(_:List[Var], otherthan, _:Formula)
override def toString() = { override def toString() = {
s"$qname ${vars.map(_.withType()).mkString(",")} ∉ {${otherthan.map(_.withType()).mkString(",")}}. ${t.bracketed()}" s"$qname ${vars.map(_.withType()).mkString(",")} ∉ {${otherthan.map(_.withType()).mkString(",")}}. ${t.bracketed()}"
} }
} }
trait TemporalTerm extends Term trait TemporalFormula extends Formula
case class Next(t: Term) extends TemporalTerm with UnOp { case class Next(t: Formula) extends TemporalFormula with UnOp {
val make = Next.apply _ val make = Next.apply _
val opname = "X" val opname = "X"
} }
case class Globally(t: Term) extends TemporalTerm with UnOp { case class Globally(t: Formula) extends TemporalFormula with UnOp {
val make = Globally.apply _ val make = Globally.apply _
val opname = "G" val opname = "G"
} }
case class Finally(t: Term) extends TemporalTerm with UnOp { case class Finally(t: Formula) extends TemporalFormula with UnOp {
val make = Finally.apply _ val make = Finally.apply _
val opname = "F" val opname = "F"
} }
case class Until(t1: Term, t2: Term) extends TemporalTerm with BinOp { case class Until(t1: Formula, t2: Formula) extends TemporalFormula with BinOp {
val make = Until.apply _ val make = Until.apply _
val opname = "U" val opname = "U"
} }
object WUntil { object WUntil {
def apply(t1: Term, t2: Term) = Or(Until(t1, t2), Globally(t1)) def apply(t1: Formula, t2: Formula) = Or(Until(t1, t2), Globally(t1))
} }
trait UnOp extends Term { trait UnOp extends Formula {
def make: Term => UnOp def make: Formula => UnOp
def opname: String def opname: String
def t: Term def t: Formula
override def toString() = opname + " " + t.bracketed() override def toString() = opname + " " + t.bracketed()
} }
...@@ -131,11 +131,11 @@ object FOLTL { ...@@ -131,11 +131,11 @@ object FOLTL {
} }
} }
trait BinOp extends Term { trait BinOp extends Formula {
def make: (Term, Term) => BinOp def make: (Formula, Formula) => BinOp
def opname: String def opname: String
def t1: Term def t1: Formula
def t2: Term def t2: Formula
override def toString() = { override def toString() = {
(t1, t2) match { (t1, t2) match {
...@@ -152,7 +152,7 @@ object FOLTL { ...@@ -152,7 +152,7 @@ object FOLTL {
Some((binop.make, binop.t1, binop.t2)) Some((binop.make, binop.t1, binop.t2))
} }
def makeL(make: (Term, Term) => Term, l: Seq[Term], Empty: Term): Term = { def makeL(make: (Formula, Formula) => Formula, l: Seq[Formula], Empty: Formula): Formula = {
l.toList match { l.toList match {
case List(x) => x case List(x) => x
case Empty :: xs => makeL(make, xs, Empty) case Empty :: xs => makeL(make, xs, Empty)
...@@ -163,44 +163,44 @@ object FOLTL { ...@@ -163,44 +163,44 @@ object FOLTL {
} }
object Or { object Or {
def make(terms: List[Term]) = { def make(terms: List[Formula]) = {
BinOp.makeL(Or.apply _, terms, True) BinOp.makeL(Or.apply _, terms, True)
} }
def make(terms: Term*) = { def make(terms: Formula*) = {
BinOp.makeL(Or.apply _, terms, False) BinOp.makeL(Or.apply _, terms, False)
} }
} }
case class Or(t1: Term, t2: Term) extends BinOp { case class Or(t1: Formula, t2: Formula) extends BinOp {
val opname = "∨" val opname = "∨"
val make = Or.apply _ val make = Or.apply _
} }
object And { object And {
def make(terms: List[Term]) = { def make(terms: List[Formula]) = {
BinOp.makeL(And.apply _, terms, True) BinOp.makeL(And.apply _, terms, True)
} }
def make(terms: Term*) = { def make(terms: Formula*) = {
BinOp.makeL(And.apply _, terms, True) BinOp.makeL(And.apply _, terms, True)
} }
} }
case class And(t1: Term, t2: Term) extends BinOp { case class And(t1: Formula, t2: Formula) extends BinOp {
val opname = "∧" val opname = "∧"
val make = And.apply _ val make = And.apply _
} }
case class Eq(t1: Term, t2: Term) extends BinOp { case class Eq(t1: Formula, t2: Formula) extends BinOp {
val opname = "↔" val opname = "↔"
val make = Eq.apply _ val make = Eq.apply _
} }
case class Implies(t1: Term, t2: Term) extends BinOp { case class Implies(t1: Formula, t2: Formula) extends BinOp {
val opname = "→" val opname = "→"
val make = Implies.apply _ val make = Implies.apply _
} }
case class Neg(t: Term) extends UnOp { case class Neg(t: Formula) extends UnOp {
val make = Neg.apply _ val make = Neg.apply _
val opname = "¬" val opname = "¬"
} }
......
...@@ -3,10 +3,10 @@ package de.tum.workflows.foltl ...@@ -3,10 +3,10 @@ package de.tum.workflows.foltl
import FOLTL._ import FOLTL._
import com.typesafe.scalalogging.LazyLogging import com.typesafe.scalalogging.LazyLogging
object TermFunctions extends LazyLogging { object FormulaFunctions extends LazyLogging {
def freeVars(t: Term) = { def freeVars(t: Formula) = {
def free(t: Term, bound: Set[Var]): Set[Var] = { def free(t: Formula, bound: Set[Var]): Set[Var] = {
t match { t match {
// Extractors // Extractors
// Exists, Forall // Exists, Forall
...@@ -24,8 +24,8 @@ object TermFunctions extends LazyLogging { ...@@ -24,8 +24,8 @@ object TermFunctions extends LazyLogging {
free(t, Set()) free(t, Set())
} }
def simplify(t: Term): Term = { def simplify(t: Formula): Formula = {
val simp: PartialFunction[Term, Term] = { val simp: PartialFunction[Formula, Formula] = {
// Push negation inward // Push negation inward
case Neg(Or(t1, t2)) => And(Neg(t1), Neg(t2)) case Neg(Or(t1, t2)) => And(Neg(t1), Neg(t2))
case Neg(And(t1, t2)) => Or(Neg(t1), Neg(t2)) case Neg(And(t1, t2)) => Or(Neg(t1), Neg(t2))
...@@ -76,7 +76,7 @@ object TermFunctions extends LazyLogging { ...@@ -76,7 +76,7 @@ object TermFunctions extends LazyLogging {
if (t == t1) t1 else simplify(t1) if (t == t1) t1 else simplify(t1)
} }
def everywhere(trans: PartialFunction[Term, Term], t: Term): Term = { def everywhere(trans: PartialFunction[Formula, Formula], t: Formula): Formula = {
if (trans.isDefinedAt(t)) if (trans.isDefinedAt(t))
trans(t) trans(t)
else else
...@@ -89,7 +89,7 @@ object TermFunctions extends LazyLogging { ...@@ -89,7 +89,7 @@ object TermFunctions extends LazyLogging {
} }
} }
def opsize(t: Term): Int = { def opsize(t: Formula): Int = {
t match { t match {
// Extractors // Extractors
case Quantifier(_, ps, t) => 1 + t.opsize() case Quantifier(_, ps, t) => 1 + t.opsize()
...@@ -99,7 +99,7 @@ object TermFunctions extends LazyLogging { ...@@ -99,7 +99,7 @@ object TermFunctions extends LazyLogging {
} }
} }
def collect[T](combine: (T*) => T, empty: T)(coll: PartialFunction[Term, T], t: Term): T = { def collect[T](combine: (T*) => T, empty: T)(coll: PartialFunction[Formula, T], t: Formula): T = {
if (coll.isDefinedAt(t)) if (coll.isDefinedAt(t))
coll(t) coll(t)
else else
...@@ -112,7 +112,7 @@ object TermFunctions extends LazyLogging { ...@@ -112,7 +112,7 @@ object TermFunctions extends LazyLogging {
} }
} }
def collect[T](coll: PartialFunction[Term, List[T]], t: Term): List[T] = { def collect[T](coll: PartialFunction[Formula, List[T]], t: Formula): List[T] = {
if (coll.isDefinedAt(t)) if (coll.isDefinedAt(t))
coll(t) coll(t)
else else
...@@ -125,25 +125,25 @@ object TermFunctions extends LazyLogging { ...@@ -125,25 +125,25 @@ object TermFunctions extends LazyLogging {
} }
} }
def assumeEmpty(t: Term, name: String) = { def assumeEmpty(t: Formula, name: String) = {
t.everywhere({ t.everywhere({
case Fun(f, _, _) if f == name => False case Fun(f, _, _) if f == name => False
}) })
} }
def annotate(t: Term, name: String) = { def annotate(t: Formula, name: String) = {
t.everywhere({ t.everywhere({
case Fun(f, None, xs) => Fun(f, Some(name), xs) case Fun(f, None, xs) => Fun(f, Some(name), xs)
}) })
} }
def annotate(t: Term, name: String, ignore: Set[String]) = { def annotate(t: Formula, name: String, ignore: Set[String]) = {
t.everywhere({ t.everywhere({
case Fun(f, None, xs) if (!(ignore contains f)) => Fun(f, Some(name), xs) case Fun(f, None, xs) if (!(ignore contains f)) => Fun(f, Some(name), xs)
}) })
} }
def checkSanity(t: Term) = { def checkSanity(t: Formula) = {
// TODO add more things, f.e. existentials // TODO add more things, f.e. existentials
// T1, T2 can appear freely // T1, T2 can appear freely
val frees = t.freeVars() -- Set(Var(Properties.T1), Var(Properties.T2)) val frees = t.freeVars() -- Set(Var(Properties.T1), Var(Properties.T2))
......
...@@ -67,10 +67,10 @@ object Causal { ...@@ -67,10 +67,10 @@ object Causal {
object Noninterference extends LazyLogging { object Noninterference extends LazyLogging {
def buildViolations(vars:List[Var], t:Term, causals:List[Var]) = { def buildViolations(vars:List[Var], t:Formula, causals:List[Var]) = {
val univ = causals.groupBy(_.typ).withDefault(_ => List()) val univ = causals.groupBy(_.typ).withDefault(_ => List())
def build(agents:List[Var], t:Term):List[Term] = { def build(agents:List[Var], t:Formula):List[Formula] = {
agents match {