Example #1
0
def test_spot_substitute_tt_ff():
    """ Test AP subsitution only. """

    # Define true and false formula
    tt = spot.formula("true")
    ff = spot.formula("false")

    # Try substituting true with true/false (nothing should happen)
    new_f = tt.substitute(formula=tt, new_formula=tt)
    assert new_f == tt

    new_f = tt.substitute(formula=tt, new_formula=ff)
    assert new_f == tt

    new_f = tt.substitute(formula=ff, new_formula=tt)
    assert new_f == tt

    new_f = tt.substitute(formula=ff, new_formula=ff)
    assert new_f == tt

    # Try substituting true with true/false (nothing should happen)
    new_f = ff.substitute(formula=tt, new_formula=tt)
    assert new_f == ff

    new_f = ff.substitute(formula=tt, new_formula=ff)
    assert new_f == ff

    new_f = ff.substitute(formula=ff, new_formula=tt)
    assert new_f == ff

    new_f = ff.substitute(formula=ff, new_formula=ff)
    assert new_f == ff
Example #2
0
 def isGeneral(self, bc1, bc2):
   if type(bc1) is str:
     bc1 = spot.formula(bc1)
   if type(bc2) is str:
     bc2 = spot.formula(bc2)
   if not sat_check(spot.formula_And([bc2, spot.formula_Not(bc1)]).to_str('spin')):
     return True
   else:
     return False
Example #3
0
 def isWitness(self, bc1, bc2):
   if type(bc1) is str:
     bc1 = spot.formula(bc1)
   if type(bc2) is str:
     bc2 = spot.formula(bc2)
   # if self.isGeneral(bc1, bc2):
   #   print('just genral')
   #   return False
   if not self.isBC(spot.formula_And([bc2, spot.formula_Not(bc1)])):
     return True
   else:
     return False
Example #4
0
def compute_results(formulas, toolnames, tools):
    '''Runs each tool from `toolnames` on each formula from `formulas`
    and stores the results in a pandas DataFrame, which is returned.'''
    data = [
        [i,str(spot.formula(formula)),is_interesting(str(spot.formula(formula))) ] +\
                 [get_states_number(tools[name],formula) for name in toolnames]
        for i,formula in enumerate(formulas)
    ]
    return pd.DataFrame.from_records(
        data,
        columns=['form_id', 'formula', 'interesting'] + toolnames,
        index='form_id')
Example #5
0
 def isBC(self, bc, show_reason = False):
   if type(bc) is str:
     bc = spot.formula(bc)
   c = spot.language_containment_checker()
   #non-triviality
   if not sat_check(bc.to_str('spin')) or not sat_check(spot.formula_Not(bc).to_str('spin')):
     if show_reason:
       print('bc is true or false')
     return False
   not_g = spot.formula_Not(spot.formula_And(self.goals))
   if not sat_check(spot.formula_And([not_g, spot.formula_Not(bc)]).to_str('spin')) and not sat_check(spot.formula_And([spot.formula_Not(not_g), bc]).to_str('spin')):
     if show_reason:
       print('trivial')
     return False
   #logical incosistency
   if sat_check(spot.formula_And(self.doms + self.goals + [bc,]).to_str('spin')):
     if show_reason:
       print('consistency')
     return False
   else:
   #minimality
     for i in range(len(self.goals)):
       if not sat_check(spot.formula_And(self.doms + [goal for goal in self.goals if goal != self.goals[i]] + [bc,]).to_str('spin')):
         if show_reason:
           print('not minimality')
           print(i, self.goals[i].to_str())
         return False
   return True
def get_pbcs_from_aut(aut):
  pbcs = []
  acc = []
  for s in range(0, aut.num_states()):
    if aut.state_is_accepting(s):
      acc.append(s)

  for acc_i in acc:
    aut_temp = spot.automaton(aut.to_str('hoa', '1.1'))
    for acc_j in acc:
      if acc_j != acc_i:
        for t in aut_temp.out(acc_j):
          t.cond = buddy.bddfalse
    run = aut_temp.accepting_run()
    plist = [p for p in run.prefix]
    pbct = spot.formula_tt()
    step = 0
    for p in plist:
      p_step = spot.bdd_format_formula(aut.get_dict(), p.label)
      p_step = spot.formula(p_step)
      for i in range(step):
        p_step = spot.formula_X(p_step)
      pbct = spot.formula_And([pbct, p_step])
      step += 1
    pbcs.append(pbct)
  return pbcs
def get_automaton():
    input = request.forms.get('query')
    spot.setup()
    f = spot.formula(input)
    a = f.translate('monitor')
    output = a.to_str('dot')
    return output
Example #8
0
def rewrite_weakuntil(input_line):
    formula = spot.formula(input_line.strip())
    newformula = "{0:[W]}".format(formula).replace('1', 'true').replace(
        '0', 'false')
    print('{:10}'.format("Original:"), input_line.strip()[2:-2])
    print('{:10}'.format("Spot:"), newformula)
    return newformula
def do_split(f, in_list):
    aut = spot.translate(f)
    inputs = spot.buddy.bddtrue
    for a in in_list:
        inputs &= spot.buddy.bdd_ithvar(aut.get_dict().varnum(spot.formula(a)))
    s = spot.split_2step(aut, inputs)
    return aut, s
Example #10
0
def spotify(ltl_formula):
    ltl_spot = _get_spot_format(ltl_formula)
    f = spot.formula(ltl_spot)
    f = spot.simplify(f)
    ltl_spot = f.__format__("l")
    # return ltl_spot
    return f  #.to_str('latex')
def test():
    input = '(Ga -> Gb) W c'
    spot.setup()
    f = spot.formula(input)
    a = f.translate('tgba')
    output = a.to_str('dot')
    return output
Example #12
0
    def selector_for_ltl(self,
                         formula,
                         init_states=None,
                         cap=inf,
                         SolverClass=GoalLeaningES,
                         keep_product=False):
        """
        Get selector for almost surely satisfaction of specification given as
        ltl formula.

        Currently, only the recurrence fragment is supported.

        Translate the formula into equivalent deterministic Büchi automaton,
        build a product of the lCMDP with the automaton and synthesise
        strategy for Büchi objective with targets in states of the product
        with accepting state in the automaton component.

        If `init_states` are given, only consider these states as possible
        initial states. This can save the algorithm from building parts of
        the product that would never be used.

        After the product is analyzed, it is discarded and no longer available,
        unless `keep_product` is `True`. In this case, the product MDP object
        is accessible by `selector.product_mdp`.

        The returned selector is intended to be passed to DBACounterStrategy
        that work directly on top of this LabeledConsMDP.

        Parameters
        ==========

         * formula: formula from the recurrence fragment of LTL in format that
            is readable by Spot's Python binding.

         * init_states: iterable of ints, the set of initial states of the
             LabeledConsMDP `self`. The product will be started from these states only.
             If `None`, all states are considered initial. At least one state
             must be declared as initial.
        * SolverClass of energy solvers to be used for analysis of the
            product (GoalLeaningES by default)
        * keep_product: Bool, default False.
            Keep the product MDP associated to the returned selector.

        Returns: `ProductSelector` for Büchi objective given by determinstic
            Büchi automaton `aut`.
        """
        f = spot.formula(formula)
        if f.mp_class() not in "SRPOBG":
            raise ValueError(
                "The formula must be from the recurrence fragment"
                "of LTL. See https://spot.lrde.epita.fr/hierarchy.html"
                f"for more details. The formula {f} was given.")
        dba = spot.translate(f, "BA", "deterministic", "complete")
        return self.selector_for_dba(aut=dba,
                                     init_states=init_states,
                                     cap=cap,
                                     SolverClass=SolverClass,
                                     keep_product=keep_product)
Example #13
0
def progress_and_clean(ltl_formula, truth_assignment):
    ltl = progress(ltl_formula, truth_assignment)
    # I am using spot to simplify the resulting ltl formula
    ltl_spot = _get_spot_format(ltl)
    f = spot.formula(ltl_spot)
    f = spot.simplify(f)
    ltl_spot = f.__format__("l")
    ltl_std, r = _get_std_format(ltl_spot.split(' '))
    assert len(r) == 0, "Format error" + str(ltl_std) + " " + str(r)
    return ltl_std
Example #14
0
def test_spot_substitute_ap():
    """ Test AP subsitution only. """

    a = spot.formula("a")
    b = spot.formula("b")
    tt = spot.formula("true")
    ff = spot.formula("false")

    # Substitute a
    new_f = a.substitute(formula=a, new_formula=tt)
    assert new_f == tt

    new_f = a.substitute(formula=a, new_formula=ff)
    assert new_f == ff

    new_f = a.substitute(formula=a, new_formula=a)
    assert new_f == a

    new_f = a.substitute(formula=a, new_formula=b)
    assert new_f == b
Example #15
0
def spot_get_trace(formula_str, simplify):
    spot_formula = spot.formula(formula_str)
    automaton = spot_formula.translate()
    automaton.merge_edges()
    acc_run = automaton.accepting_run()
    if acc_run is None:
        return False, None
    else:
        trace = spot.twa_word(acc_run)
        if simplify:
            trace.simplify()
        return True, str(trace)
Example #16
0
def test_spot_substitute_pl():
    """ Test AP subsitution only. """

    a = spot.formula("a")
    b = spot.formula("b")
    tt = spot.formula("true")
    ff = spot.formula("false")

    phi0 = spot.formula("!a")
    phi1 = spot.formula("a & b")

    # Substitute phi0
    new_f = phi0.substitute(formula=a, new_formula=tt)
    assert new_f == ff

    new_f = phi0.substitute(formula=a, new_formula=ff)
    assert new_f == tt

    new_f = phi0.substitute(formula=a, new_formula=b)
    assert new_f == spot.formula("!b")

    new_f = phi0.substitute(formula=phi0, new_formula=b)
    assert new_f == spot.formula("b")

    # Substitute phi1
    new_f = phi1.substitute(formula=a, new_formula=tt)
    assert new_f == spot.formula("b")

    new_f = new_f.substitute(formula=b, new_formula=tt)
    assert new_f == tt

    new_f = phi1.substitute(formula=a, new_formula=ff)
    assert new_f == ff

    # Substitute a with b
    new_f = phi1.substitute(formula=a, new_formula=b)
    assert new_f == spot.formula("b")
Example #17
0
    def form_of_id(self, form_id, spot_obj=True):
        """For given form_id returns the formula

        Parameters
        ----------
        form_id : int
            id of formula to return
        spot_obj : Bool
            If ``True``, returns Spot formula object (uses Latex to
            print the formula in Jupyter notebooks)
        """
        f = self.values.index[form_id][1]
        if spot_obj:
            return spot.formula(f)
        return f
Example #18
0
def explain_stut(f):
    f = spot.formula(f)
    pos = spot.translate(f)
    neg = spot.translate(spot.formula.Not(f))
    word = spot.product(spot.closure(pos), spot.closure(neg)).accepting_word()
    if word is None:
        print(f, "is stutter invariant")
        return
    word.simplify()
    # This line used to be missing, causing issue #388.
    word.use_all_aps(pos.ap_vars())
    waut = word.as_automaton()
    aut = neg if waut.intersects(pos) else pos
    word2 = spot.sl2(waut).intersecting_word(aut)
    word2.simplify()
    return(word, word2)
Example #19
0
def translate(inp):
    """Translate input to polish pred Logic.

    input: ltl no matter what form.
    output: ltl in polish notation

    >>> from LTL.tools.ltlToPred import translate
    >>> translate('[]<>p0')
    'G F p0'
    >>> translate('p1 U (p2 & GFp3)')
    'U p1 & p2 G F p3'

    """
    f = spot.formula(inp)
    lbt = f.to_str('lbt')

    return lbt
Example #20
0
 def _to_automaton(self):
     self._spot_formula = spot.formula(self._formula)
     # Follow https://spot.lrde.epita.fr/tut12.html to convert to finite semantics
     aut = spot.from_ltlf(self._formula).translate('low', 'sbacc')
     rem = spot.remove_ap()
     rem.add_ap('alive')
     aut = rem.strip(aut)
     aut = spot.postprocess(aut, 'low', 'sbacc')
     self._spot_automaton = aut
     init_states = [d for d in aut.univ_dests(aut.get_init_state_number())]
     bdd_dict = aut.get_dict()
     for s in range(aut.num_states()):
         is_init = s in init_states
         is_accepting = aut.state_is_accepting(s)
         self.add_state(str(s), init=is_init, accept=is_accepting)
     state_id = aut.num_states()
     for ed in aut.edges():
         label = spot.bdd_to_formula(ed.cond, bdd_dict)
         if self._add_flexible_state and str(ed.src) != str(ed.dst):
             state_name = 'e_' + str(state_id)
             self.add_state(state_name)
             # add transition to the new state
             self.add_transition(str(ed.src), state_name, label='1')
             # add transition of the self loop
             self.add_transition(state_name, state_name, label='1')
             # add transition from the new state to destination
             self.add_transition(state_name, str(ed.dst), label=str(label))
             state_id += 1
         else:
             self.add_transition(str(ed.src), str(ed.dst), label=str(label))
     if self._alphabets is None:
         self._alphabets = set()
         for ap in spot.atomic_prop_collect(self._spot_formula):
             self._alphabets.add(str(ap))
     # replace all '1' labels to be all possible alphabets
     for src, dst, label in self._graph.edges(data='label'):
         if self._graph[src][dst]['label'] == '1':
             self._graph[src][dst]['label'] = self._get_alphabet_str()
             self._graph[src][dst]['print_label'] = '1'
         elif self._graph[src][dst]['label'] == '0':
             self._graph[src][dst]['label'] = self._get_neg_alphabet_str()
             self._graph[src][dst]['print_label'] = '0'
         else:
             self._graph[src][dst]['print_label'] = self._graph[src][dst][
                 'label']
Example #21
0
  def isBC_t(self, bc, no_relation_gi):
    if type(bc) is str:
      bc = spot.formula(bc)

    #logical incosistency
    if sat_check(spot.formula_And(self.doms + self.goals + [bc,]).to_str('spin')):
      return -1
    else:
    #minimality
      no_relation_g = []
      for i in range(len(self.goals)):
        if i in no_relation_gi:
          no_relation_g.append(self.goals[i])

      for i in range(len(self.goals)):
        if i in no_relation_gi:
          continue
        if not sat_check(spot.formula_And(self.doms + [goal for goal in self.goals if goal != self.goals[i] and goal not in no_relation_g] + [bc,]).to_str('spin')):
          return i
    return -2
Example #22
0
def test_spot_substitute_error():
    a = spot.formula("a U b")

    with pytest.raises(ValueError):
        a.substitute(formula=a, new_formula=spot.formula("true"))
Example #23
0
try:
    a = r.replay(spot.get_cout())
except RuntimeError as e:
    assert "empty cycle" in str(e)
else:
    report_missing_exception()

try:
    a = r.reduce()
except RuntimeError as e:
    assert "empty cycle" in str(e)
else:
    report_missing_exception()

f = spot.formula('GF(a | Gb)')
try:
    spot.gf_guarantee_to_ba(f, spot._bdd_dict)
except RuntimeError as e:
    assert "guarantee" in str(e)
else:
    report_missing_exception()

f = spot.formula('FG(a | Fb)')
try:
    spot.fg_safety_to_dca(f, spot._bdd_dict)
except RuntimeError as e:
    assert "safety" in str(e)
else:
    report_missing_exception()
Example #24
0
def test_graph_tool():
    import spot
    spot.formula('a')
Example #25
0
# +
import spot
spot.setup()
from spot.jupyter import display_inline

from math import inf

from fimdp.labeled import DBAWrapper, LabeledConsMDP
from fimdp.energy_solvers import BasicES
from fimdp.objectives import BUCHI

# -

# ### Test DBAWrapper

f = spot.formula("GF b & GF a")
aut = spot.translate(f, "BA", "deterministic", "complete")

aut

# +
AP = ["a", "b"]
wrapper = DBAWrapper(aut, AP)

a = AP.index("a")
b = AP.index("b")
assert wrapper.succ(2, [a]) == 1
assert wrapper.succ(2, [a, b]) == 2
assert wrapper.succ(2, [b]) == 0
assert wrapper.succ(2, []) == 1
Example #26
0
#!/usr/bin/python3
import spot
from functools import reduce

ltl = spot.formula(
    "G(trigger -> X(policy  W (!trigger & terminate & callback)))")
GR1 = ([
    "!triggered",  # Init
    "G((trigger | (triggered & !terminate))<-> X(triggered))",  # Keeps Triggering
    "G(triggered -> policy)",  # Current State
    "G((!trigger & terminate ) -> callback)"  # Callback Action
])
translated_gr1 = (reduce(lambda x, y: spot.product(x, y),
                         map(spot.translate, map(spot.formula, GR1))))
ltl_n = spot.formula.Not(ltl).translate()
ans = spot.product(translated_gr1, ltl_n)
print(ans.is_empty())
print(ans.accepting_word())
Example #27
0
# along with this program.  If not, see <http://www.gnu.org/licenses/>.

import spot

lcc = spot.language_containment_checker()

formulas = ['GFa', 'FGa', '(GFa) U b',
            '(a U b) U c', 'a U (b U c)',
            '(a W b) W c', 'a W (b W c)',
            '(a R b) R c', 'a R (b R c)',
            '(a M b) M c', 'a M (b M c)',
            '(a R b) U c', 'a U (b R c)',
            '(a M b) W c', 'a W (b M c)',
            '(a U b) R c', 'a R (b U c)',
            '(a W b) M c', 'a M (b W c)',
            ]

# The rewriting assume the atomic proposition will not change
# once we reache the non-alive part.
cst = spot.formula('G(X!alive => ((a <=> Xa) && (b <=> Xb) && (c <=> Xc)))')

for f in formulas:
    f1 = spot.formula(f)
    f2 = f1.unabbreviate()
    f3 = spot.formula_And([spot.from_ltlf(f1), cst])
    f4 = spot.formula_And([spot.from_ltlf(f2), cst])
    print("{}\t=>\t{}".format(f1, f3))
    print("{}\t=>\t{}".format(f2, f4))
    assert lcc.equal(f3, f4)
    print()
Example #28
0
# Spot is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3 of the License, or
# (at your option) any later version.
#
# Spot is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
# or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
# License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.

import spot

f = spot.formula('GF(a & b) -> (FG(a & b) & Gc)')
m = spot.relabeling_map()
g = spot.relabel_bse(f, spot.Pnn, m)
res = ""
for old, new in m.items():
    res += "#define {} {}\n".format(old, new)
res += str(g)
print(res)
assert(res == """#define p0 a & b
#define p1 c
GFp0 -> (FGp0 & Gp1)""")


autg = g.translate()
spot.relabel_here(autg, m)
assert str(autg.ap()) == '(a, b, c)'
Example #29
0
T = spot.formula.tt()
F = spot.formula.ff()

f1 = spot.formula.Equiv(c, a)
f2 = spot.formula.Implies(a, b)
f3 = spot.formula.Xor(b, c)
f4 = spot.formula.Not(f3)
del f3
f5 = spot.formula.Xor(F, c)

del a, b, c, T, F, f1, f2, f4, f5

assert spot.fnode_instances_check()

#----------------------------------------------------------------------
assert str([x for x in spot.formula('a &b & c')]) == '[a, b, c]'


def switch_g_f(x):
    if x._is(spot.op_G):
        return spot.formula.F(switch_g_f(x[0]))
    if x._is(spot.op_F):
        return spot.formula.G(switch_g_f(x[0]))
    return x.map(switch_g_f)


f = spot.formula('GFa & XFGb & Fc & G(a | b | Fd)')
assert str(switch_g_f(f)) == 'FGa & XGFb & Gc & F(a | b | Gd)'

x = 0
Example #30
0
# along with this program.  If not, see <http://www.gnu.org/licenses/>.

import spot

lcc = spot.language_containment_checker()

formulas = ['GFa', 'FGa', '(GFa) U b',
            '(a U b) U c', 'a U (b U c)',
            '(a W b) W c', 'a W (b W c)',
            '(a R b) R c', 'a R (b R c)',
            '(a M b) M c', 'a M (b M c)',
            '(a R b) U c', 'a U (b R c)',
            '(a M b) W c', 'a W (b M c)',
            '(a U b) R c', 'a R (b U c)',
            '(a W b) M c', 'a M (b W c)',
           ]

# The rewriting assume the atomic proposition will not change
# once we reache the non-alive part.
cst = spot.formula('G(X!alive => ((a <=> Xa) && (b <=> Xb) && (c <=> Xc)))')

for f in formulas:
    f1 = spot.formula(f)
    f2 = f1.unabbreviate()
    f3 = spot.formula_And([spot.from_ltlf(f1), cst])
    f4 = spot.formula_And([spot.from_ltlf(f2), cst])
    print("{}\t=>\t{}".format(f1, f3))
    print("{}\t=>\t{}".format(f2, f4))
    assert lcc.equal(f3, f4)
    print()
Example #31
0
                if not j.startswith('DRA'):
                    if s < mins:
                        mins = s
                    if a < mina:
                        mina = a
                else:
                    hl = False;
                    if s < mins:
                        val = '\\textbf{' + val + '}'
                        hl = True
                    if a < mina:
                        a = '\\textbf{' + str(a) + '}'
                        hl = True
                    if hl:
                        val = '\\E ' + val
                val += ' (' + str(a) + ')'
        except KeyError:
            val = 'na'
        print("&", val, end=' ')


for i in l:
    mins = 999999
    mina = 999999
    print('$' + spot.formula(i).to_str('latex') + '$', end=' ')
    print_half_line(i, csv_s, ts)
    print_half_line(i, csv_t, tt)
    print("\\\\")
print("""\end{tabular}
\end{document}""")
import spot
import pdb
ltl = "(a U b) & GFc & GFd"

safety = spot.formula("!a U b")
safety_aut = spot.translate(safety, "deterministic", "BA", "sbacc")
ra = spot.to_generalized_rabin(safety_aut)
ra = spot.split_edges(ra)


def get_edges_labels(a):
    bddict = a.get_dict()
    edges = []
    labels = []
    for s in range(0, a.num_states()):
        print("State :{}".format(s))
        for t in a.out(s):
            ud = a.is_univ_dest(t)
            if not ud:
                for dest in a.univ_dests(t):
                    print("adding edge {}".format((int(t.src), int(dest))))
                    print("with label {}".format(
                        spot.bdd_to_formula(t.cond, bddict)))
                    edges.append((int(t.src), int(dest)))
                    labels.append(spot.bdd_to_formula(t.cond, bddict))


edges, labels = get_edges_labels(ra)

for e in ra.edges():
    print("edge {}".format((int(e.src), int(e.dst))))
Example #33
0
def test_phi(phi):
    a =  spot.translate(phi, 'TGBA', 'SBAcc')
    res = spot.to_weak_alternating(spot.dualize(a))
    assert equivalent(res, spot.formula.Not(spot.formula(phi)))
Example #34
0
c = spot.formula.ap('c')
T = spot.formula.tt()
F = spot.formula.ff()

f1 = spot.formula.Equiv(c, a)
f2 = spot.formula.Implies(a, b)
f3 = spot.formula.Xor(b, c)
f4 = spot.formula.Not(f3); del f3
f5 = spot.formula.Xor(F, c)

del a, b, c, T, F, f1, f2, f4, f5

assert spot.fnode_instances_check()

#----------------------------------------------------------------------
assert str([x for x in spot.formula('a &b & c')]) == '[a, b, c]'


def switch_g_f(x):
    if x._is(spot.op_G):
        return spot.formula.F(switch_g_f(x[0]))
    if x._is(spot.op_F):
        return spot.formula.G(switch_g_f(x[0]))
    return x.map(switch_g_f)

f = spot.formula('GFa & XFGb & Fc & G(a | b | Fd)')
assert str(switch_g_f(f)) == 'FGa & XGFb & Gc & F(a | b | Gd)'

x = 0
def count_g(f):
    global x
Example #35
0
def equivalent(a, phi):
    negphi = spot.formula.Not(phi)
    nega = spot.dualize(a)
    return not (spot.translate(negphi).intersects(a)
                or spot.translate(phi).intersects(nega))

def test_phi(phi):
    a =  spot.translate(phi, 'TGBA', 'SBAcc')
    res = spot.to_weak_alternating(spot.dualize(a))
    assert equivalent(res, spot.formula.Not(spot.formula(phi)))

for p in phi1.split('\n'):
    print(p)
    test_phi(p)

phi2 = spot.formula("(G((F a) U b)) W a")
a2 = spot.automaton("""
HOA: v1
States: 7
Start: 1
AP: 2 "a" "b"
acc-name: generalized-Buchi 2
Acceptance: 2 Inf(0)&Inf(1)
properties: trans-labels explicit-labels trans-acc complete univ-branch
--BODY--
State: 0
[t] 0 {0 1}
State: 1
[0] 0 {0 1}
[1] 1&2 {0 1}
[0&!1] 1&3 {0 1}
Example #36
0
#!/usr/bin/python3
import spot
precede = spot.formula(" ((F after) -> ( (!after) U ((!after) & before) ))")
gr1 = spot.formula(
    " (!before & !s & !after) & G( (!s & !before)->X(!s) ) &G(before->X(s))  & G((!s)->(!after)) & G(s->X(s))"
)


def implies(f, g):
    a_f = f.translate()
    a_ng = spot.formula.Not(g).translate()
    return spot.product(a_f, a_ng)


r1 = (implies(precede, gr1))
print(r1.is_empty())
print(r1.accepting_word())

r2 = (implies(gr1, precede))
print(r2.is_empty())
print(r2.accepting_word())
Example #37
0
def calculate_accuracy(formulas_file, traces_file, targets_file, log_file,
                       sat_prob_file, polish, sem_desp_syn, per_size,
                       validator, log_level, **kwargs):
    with nice_open(formulas_file, 'r') as formulas, nice_open(
            traces_file,
            'r') as traces, nice_open(targets_file, 'r') as targets, nice_open(
                log_file, 'w') as log, nice_open(sat_prob_file,
                                                 'w') as sat_prob:
        line_num = 0
        tictoc = TicToc()
        if per_size:
            res = {
                'syntactically correct': {},
                'only semantically correct': {},
                'incorrect': {},
                'invalid': {},
                'unknown': {}
            }

            def increment(key, formula_obj):
                size = formula_obj.size()
                if size in res[key]:
                    res[key][size] += 1
                else:
                    res[key][size] = 1
        else:
            res = {
                'syntactically correct': 0,
                'only semantically correct': 0,
                'incorrect': 0,
                'invalid': 0,
                'unknown': 0
            }

            def increment(key, formula_obj):
                res[key] += 1

        if validator == 'spot' or validator == 'both':
            import spot

        for formula_str, trace_str in zip(formulas, traces):
            formula_str, trace_str = formula_str.strip(), trace_str.strip()
            line_num += 1
            target_str = next(targets).strip() if targets else None
            if target_str == '-':  # no trace
                target_str = None
            formula_format = 'network-' + ('polish' if polish else 'infix')
            formula_obj = ltl_parser.ltl_formula(formula_str,
                                                 format=formula_format)

            # trace valid syntactically?
            try:
                trace_obj = ltl_parser.ltl_trace(trace_str,
                                                 format=formula_format)
            except ltl_parser.ParseError as e:
                increment('invalid', formula_obj)
                if log and log_level >= 1:
                    log.write(
                        "INVALID {:d}\ninput  (raw): {}\noutput (raw): {}\ntarget (raw): {}\nerror: {}\n\n"
                        .format(line_num, formula_str, trace_str, target_str,
                                e))
                continue

            # trace equal to target (if available)?
            if target_str:  # target available
                target_obj = ltl_parser.ltl_trace(target_str,
                                                  format=formula_format)
                if trace_obj.equal_to(target_obj, extended_eq=True):
                    increment('syntactically correct', formula_obj)
                    syntactically_correct = True
                    if log and log_level >= 4:
                        log.write(
                            "SYNTACTICALLY CORRECT {:d}\ninput : {}\noutput: {}\n\n"
                            .format(line_num, formula_obj.to_str('spot'),
                                    trace_obj.to_str('spot')))
                    if not sem_desp_syn:
                        continue
                else:
                    syntactically_correct = False
            else:
                target_obj = None
                syntactically_correct = None

            # sat problem
            sat_obj = encode_for_satisfiability(trace_obj, formula_obj)
            sat_formula = sat_obj.to_str('spot',
                                         spacing='all ops',
                                         full_parens=True)
            if sat_prob:
                sat_formula_conv = sat_formula.replace('1', 'True').replace(
                    '0', 'False').replace('!', '~')
                sat_prob.write(sat_formula_conv)

            # aalta trace check
            if validator == 'aalta' or validator == 'both':
                tictoc.tic()
                try:
                    aalta_result = aalta_wrapper.sat(sat_formula, timeout=20)
                    aalta_holds = not aalta_result if aalta_result is not None else None
                except RuntimeError as e:
                    aalta_holds = None
                tictoc.toc('aalta check')
            else:
                aalta_holds = None

            # spot trace check
            if validator == 'spot' or validator == 'both':
                formula_spot = spot.formula(formula_obj.to_str('spot'))
                trace_spot = spot.parse_word(trace_obj.to_str('spot'))
                tictoc.tic()
                formula_automaton = formula_spot.translate()
                trace_automaton = trace_spot.as_automaton()
                tictoc.toc('spot translate')
                tictoc.tic()
                try:
                    spot_holds = spot.contains(
                        formula_automaton, trace_automaton
                    )  # spot.contains checks whether language of its right argument is included in language of its left argument
                except RuntimeError:
                    spot_holds = None
                tictoc.toc('spot contains')
            else:
                spot_holds = None

            # compare, evaluate trace checks
            trace_holds = aalta_holds if aalta_holds is not None else spot_holds  # if both, same, else the one that is there or both None
            if validator == 'both' and aalta_holds != spot_holds:
                print('Formula ', formula_obj.to_str('spot'))
                print('Trace   ', trace_obj.to_str('spot'))
                print('Sat form', sat_formula)
                print('MISMATCH aalta: {} -- spot: {}\n'.format(
                    aalta_holds, spot_holds))
                trace_holds = spot_holds  # trust spot more
            if trace_holds is None:
                if log:
                    log.write(
                        "UNKNOWN {:d}\ninput : {}\noutput: {}\ntarget: {}\n\n".
                        format(
                            line_num, formula_obj.to_str('spot'),
                            trace_obj.to_str('spot'),
                            target_obj.to_str('spot') if target_obj else None))
                increment('unknown', formula_obj)
            elif trace_holds:
                if not sem_desp_syn or (not syntactically_correct):
                    if log and log_level >= 3:
                        log.write(
                            "SEMANTICALLY CORRECT {:d}\ninput : {}\noutput: {}\ntarget: {}\n\n"
                            .format(
                                line_num, formula_obj.to_str('spot'),
                                trace_obj.to_str('spot'),
                                target_obj.to_str('spot')
                                if target_obj else None))
                    increment('only semantically correct', formula_obj)
            else:  # dosen't hold
                increment('incorrect', formula_obj)
                if log and log_level >= 2:
                    log.write(
                        "INCORRECT {:d}\ninput : {}\noutput: {}\ntarget: {}\n\n"
                        .format(
                            line_num, formula_obj.to_str('spot'),
                            trace_obj.to_str('spot'),
                            target_obj.to_str('spot') if target_obj else None))
                if sem_desp_syn and syntactically_correct:
                    raise RuntimeError(
                        'Trace is said to be syntactically correct, but does not fulfil formula!'
                    )

        tictoc.histogram(show=False)
        # evaluation
        if per_size:
            res = per_size_analysis(res, **kwargs)
        res['total'] = line_num
        res['correct'] = res['syntactically correct'] + res[
            'only semantically correct']
        assert res['total'] == res['correct'] + res['incorrect'] + res[
            'invalid'] + res['unknown']
        res_str = "Correct: {:f}%, {correct:d} out of {total:d}\nSyntactically correct: {:f}%, {syntactically correct:d} out of {total:d}\n"\
            "Semantically correct, but not syntactically: {:f}%, {only semantically correct:d} out of {total:d}\n"\
            "Incorrect: {:f}%, {incorrect:d} out of {total:d}\nInvalid: {:f}%, {invalid:d} out of {total:d}\n"\
            "Unknown: {unknown:d} out of {total:d}\n"\
            "".format(res['correct'] / res['total'] * 100, res['syntactically correct'] / res['total'] * 100, res['only semantically correct'] / res['total'] * 100, res['incorrect'] / res['total'] * 100, res['invalid'] / res['total'] * 100, **res)
        if log and not (log is sys.stdout):
            log.write(res_str)
    return res, res_str