Skip to content
This repository has been archived by the owner on Oct 9, 2022. It is now read-only.

Commit

Permalink
Merge pull request #21 from whitemech/ltl-termination
Browse files Browse the repository at this point in the history
Support for LTLfLast.
  • Loading branch information
cipollone authored Mar 7, 2020
2 parents f65aef2 + 7f139ce commit faef451
Show file tree
Hide file tree
Showing 8 changed files with 81 additions and 26 deletions.
2 changes: 1 addition & 1 deletion flloat/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -223,7 +223,7 @@ class FiniteTraceTruth:
"""Interface for formulas that support the trace semantics."""

@abstractmethod
def truth(self, i: FiniteTrace, pos: int) -> bool:
def truth(self, i: FiniteTrace, pos: int = 0) -> bool:
"""
Return the truth evaluation of the formula wrt the trace.
Expand Down
20 changes: 10 additions & 10 deletions flloat/ldlf.py
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,7 @@ def _delta(self, i: PropositionalInterpretation, epsilon=False):
"""Apply the delta function."""
return self.to_nnf()._delta(i, epsilon=epsilon)

def truth(self, i: FiniteTrace, pos: int):
def truth(self, i: FiniteTrace, pos: int = 0):
"""Evaluate the formula."""
return self.to_nnf().truth(i, pos)

Expand Down Expand Up @@ -263,7 +263,7 @@ def negate(self) -> LDLfFormula:
"""Negate the formula."""
return self.f

def truth(self, i: FiniteTrace, pos: int) -> bool:
def truth(self, i: FiniteTrace, pos: int = 0):
"""Evaluate the formula."""
return not self.f.truth(i, pos)

Expand Down Expand Up @@ -300,7 +300,7 @@ def negate(self) -> LDLfFormula:
"""Negate the formula."""
return LDLfOr([f.negate() for f in self.formulas])

def truth(self, i: FiniteTrace, pos: int) -> bool:
def truth(self, i: FiniteTrace, pos: int = 0):
"""Evaluate the formula."""
return all(f.truth(i, pos) for f in self.formulas)

Expand All @@ -321,7 +321,7 @@ def negate(self) -> LDLfFormula:
"""Negate the formula."""
return LDLfOr([f.negate() for f in self.formulas])

def truth(self, i: FiniteTrace, pos: int) -> bool:
def truth(self, i: FiniteTrace, pos: int = 0):
"""Evaluate the formula."""
return any(f.truth(i, pos) for f in self.formulas)

Expand All @@ -338,7 +338,7 @@ def operator_symbol(self) -> OpSymbol:
"""Get the operator symbol."""
return Symbols.IMPLIES.value

def truth(self, i: FiniteTrace, pos: int):
def truth(self, i: FiniteTrace, pos: int = 0):
"""Evaluate the formula."""
return self.to_nnf().truth(i, pos)

Expand Down Expand Up @@ -369,7 +369,7 @@ def operator_symbol(self) -> OpSymbol:
"""Get the operator symbol."""
return Symbols.EQUIVALENCE.value

def truth(self, i: FiniteTrace, pos: int):
def truth(self, i: FiniteTrace, pos: int = 0):
"""Evaluate the formula."""
return self.to_nnf().truth(i, pos)

Expand Down Expand Up @@ -685,7 +685,7 @@ def find_labels(self) -> Set[AtomSymbol]:
"""Find the labels."""
return self.to_nnf().find_labels()

def truth(self, i: FiniteTrace, pos: int):
def truth(self, i: FiniteTrace, pos: int = 0):
"""Evaluate the formula."""
return self.to_nnf().truth(i, pos)

Expand Down Expand Up @@ -716,7 +716,7 @@ def find_labels(self) -> Set[AtomSymbol]:
"""Find the labels."""
return self.to_nnf().find_labels()

def truth(self, i: FiniteTrace, pos: int):
def truth(self, i: FiniteTrace, pos: int = 0):
"""Evaluate the formula."""
return self.to_nnf().truth(i, pos)

Expand Down Expand Up @@ -768,7 +768,7 @@ def find_labels(self):
"""Find the labels."""
return super().find_labels()

def truth(self, tr: FiniteTrace, pos: int):
def truth(self, tr: FiniteTrace, pos: int = 0):
"""Evaluate the formula."""
raise NotImplementedError

Expand Down Expand Up @@ -805,7 +805,7 @@ def find_labels(self):
"""Find the labels."""
return super().find_labels()

def truth(self, tr: FiniteTrace, pos: int):
def truth(self, tr: FiniteTrace, pos: int = 0):
"""Evaluate the formula."""
raise NotImplementedError

Expand Down
47 changes: 39 additions & 8 deletions flloat/ltlf.py
Original file line number Diff line number Diff line change
Expand Up @@ -219,7 +219,7 @@ def _delta(self, i: PropositionalInterpretation, epsilon=False):
"""Apply the delta function."""
return PLAnd([f._delta(i, epsilon) for f in self.formulas])

def truth(self, i: FiniteTrace, pos: int):
def truth(self, i: FiniteTrace, pos: int = 0):
"""Evaluate the formula."""
return all(f.truth(i, pos) for f in self.formulas)

Expand Down Expand Up @@ -247,7 +247,7 @@ def _delta(self, i: PropositionalInterpretation, epsilon=False):
"""Apply the delta function."""
return PLOr([f._delta(i, epsilon) for f in self.formulas])

def truth(self, i: FiniteTrace, pos: int):
def truth(self, i: FiniteTrace, pos: int = 0):
"""Evaluate the formula."""
return any(f.truth(i, pos) for f in self.formulas)

Expand All @@ -268,7 +268,7 @@ def operator_symbol(self) -> OpSymbol:
"""Get the operator symbol."""
return Symbols.IMPLIES.value

def truth(self, i: FiniteTrace, pos: int):
def truth(self, i: FiniteTrace, pos: int = 0):
"""Evaluate the formula."""
return self.to_nnf().truth(i, pos)

Expand Down Expand Up @@ -299,7 +299,7 @@ def operator_symbol(self) -> OpSymbol:
"""Get the operator symbol."""
return Symbols.EQUIVALENCE.value

def truth(self, i: FiniteTrace, pos: int):
def truth(self, i: FiniteTrace, pos: int = 0):
"""Evaluate the formula."""
return self.to_nnf().truth(i, pos)

Expand Down Expand Up @@ -504,7 +504,7 @@ def negate(self) -> LTLfFormula:
"""Negate the formula."""
return self.to_nnf().negate()

def truth(self, i: FiniteTrace, pos: int):
def truth(self, i: FiniteTrace, pos: int = 0):
"""Evaluate the formula."""
return self.to_nnf().truth(i, pos)

Expand Down Expand Up @@ -535,7 +535,7 @@ def negate(self) -> LTLfFormula:
"""Negate the formula."""
return self.to_nnf().negate()

def truth(self, i: FiniteTrace, pos: int):
def truth(self, i: FiniteTrace, pos: int = 0):
"""Evaluate the formula."""
return self.to_nnf().truth(i, pos)

Expand All @@ -544,6 +544,37 @@ def _delta(self, i: PropositionalInterpretation, epsilon=False):
return self.to_nnf()._delta(i, epsilon=epsilon)


class LTLfLast(LTLfFormula):
"""Class for the LTLf Last formula."""

def _delta(self, i: PropositionalInterpretation, epsilon=False):
"""Apply the delta function."""
return self.to_nnf()._delta(i, epsilon=epsilon)

def to_nnf(self) -> LTLfFormula:
"""Transform to NNF."""
return LTLfAnd([LTLfWeakNext(LTLfFalse()), LTLfNot(LTLfEnd())]).to_nnf()

def negate(self) -> LTLfFormula:
"""Negate the formula."""
return self.to_nnf().negate()

def truth(self, i: FiniteTrace, pos: int = 0):
"""Evaluate the formula."""
return self.to_nnf().truth(i, pos)

def find_labels(self) -> Set[AtomSymbol]:
"""Find the labels."""
return set()

def _members(self):
return (Symbols.LAST.value,)

def __str__(self):
"""Get the string representation."""
return Symbols.LAST.value


class LTLfEnd(LTLfFormula):
"""Class for the LTLf End formula."""

Expand All @@ -553,9 +584,9 @@ def _delta(self, i: PropositionalInterpretation, epsilon=False):

def find_labels(self) -> Set[AtomSymbol]:
"""Find the labels."""
return self.to_nnf().find_labels()
return set()

def truth(self, i: FiniteTrace, pos: int):
def truth(self, i: FiniteTrace, pos: int = 0):
"""Evaluate the formula."""
return self.to_nnf().truth(i, pos)

Expand Down
3 changes: 2 additions & 1 deletion flloat/parser/ltlf.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
LTLfTrue,
LTLfAtomic,
LTLfFalse,
LTLfLast,
)
from flloat.parser import CUR_DIR
from flloat.parser.pl import PLTransformer
Expand Down Expand Up @@ -159,7 +160,7 @@ def ltlf_false(self, args):
return LTLfFalse()

def ltlf_last(self, args):
raise NotImplementedError("LTLf last not supported, yet")
return LTLfLast()

def ltlf_end(self, args):
raise NotImplementedError("LTLf end not supported, yet")
Expand Down
6 changes: 3 additions & 3 deletions flloat/pl.py
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ def to_sympy(
class PLAtomic(AtomicFormula, PLFormula):
"""A class to represent propositional atomic formulas."""

def truth(self, i: PropInt, *args) -> bool:
def truth(self, i: PropInt, *args):
"""Evaluate the formula."""
return i.get(self.s, False)

Expand Down Expand Up @@ -138,7 +138,7 @@ def __init__(self):
"""Initialize the PL true formula."""
PLAtomic.__init__(self, Symbols.TRUE.value)

def truth(self, *args) -> bool:
def truth(self, *args):
"""Evaluate the formula."""
return True

Expand All @@ -162,7 +162,7 @@ def __init__(self):
"""Initialize the formula."""
PLAtomic.__init__(self, Symbols.FALSE.value)

def truth(self, *args) -> bool:
def truth(self, *args):
"""Evaluate the formula."""
return False

Expand Down
1 change: 0 additions & 1 deletion flloat/symbols.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,6 @@ class Symbols(Enum):
CARET = "^"
TRUE = "true"
FALSE = "false"
LTLf_LAST = "last"


ALL_SYMBOLS = {v.value for v in Symbols} # type: Set[str]
4 changes: 2 additions & 2 deletions tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -58,15 +58,15 @@
"F a",
"F(a & b)",
"F(a | b)",
# "F(a & last)",
"F(a & last)",
"G a",
"F(G(a))",
"G(F(a))",
"G(true)",
"F(true)",
"G(false)",
"F(false)",
# "last",
"last",
# "end",
"true",
"false",
Expand Down
24 changes: 24 additions & 0 deletions tests/test_ltlf.py
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,30 @@ def test_always(self):
assert parser("G c").truth(t, 10)
assert parser("G F c").truth(t, 0)

def test_last(self):
parser = self.parser
t = self.trace

last = parser("last")
not_last = parser("! last")

assert last.negate() == not_last.to_nnf()

for pos in range(0, 5):
assert not parser("last").truth(t, pos)
assert parser("last").truth(t, 5)
assert not parser("last").truth(t, 6)

assert parser("XXXXX last").truth(t)
assert not parser("XXXX last").truth(t)
assert not parser("XXXXX !last").truth(t)
assert parser("XXXX !last").truth(t)

assert parser("c&last").truth(t, 5)

assert parser("last").truth(t[5:])
assert not parser("last").truth(t[6:])


def test_nnf():
parser = LTLfParser()
Expand Down

0 comments on commit faef451

Please sign in to comment.