def test_forall_init(): aut = symbolic.Automaton() aut.declare_variables(x=(3, 5), y='bool', z='bool') aut.varlist = dict(env=['x'], sys=['y', 'z']) # single initial state s = '(x = 4) /\ ~ y /\ z' aut.init['env'] = aut.add_expr(s) aut.build() g = nx.DiGraph() fol = _init_context(aut) umap = dict() keys = ('x', 'z', 'y') queue, visited = enum._forall_init(g, aut, umap, keys) assert len(queue) == 1, queue (q, ) = queue assert q in g, (q, g) d = g.nodes[q] d_ = dict(x=4, y=False, z=True) assert d == d_, d # multiple initial states: should pick all s = ('(x \in 3..5) /\ (x < 5) ' '/\ ~ z /\ (z <=> TRUE \/ z <=> FALSE)') aut.init['env'] = aut.add_expr(s) aut.build() g = nx.DiGraph() umap = dict() queue, visited = enum._forall_init(g, aut, umap, keys) assert len(queue) == 4, queue varnames = {'x', 'y', 'z'} for q in queue: assert q in g, (q, g) d = g.nodes[q] assert set(d) == varnames, d assert d['x'] < 5, d assert isinstance(d['y'], bool), d assert d['z'] is False, d
def test_declare_constants(): aut = trl.Automaton() aut.declare_constants(x=(0, 5), y='bool') assert 'x' in aut.vars, aut.vars assert "x'" not in aut.vars, aut.vars assert 'y' in aut.vars, aut.vars assert "y'" not in aut.vars, aut.vars
def test_action_to_steps(): aut = symbolic.Automaton() aut.declare_variables(x='bool', y=(0, 17)) env = 'env_foo' sys = 'sys_bar' aut.varlist[env] = ['x'] aut.varlist[sys] = ['y'] keys = ('x', 'y') aut.init[env] = aut.add_expr('x /\ (y = 1)') aut.init[sys] = aut.true aut.action[env] = aut.true aut.action[sys] = aut.add_expr("y' /= y") aut.win['<>[]'] = aut.bdds_from('x') aut.win['[]<>'] = aut.bdds_from('y != 1') aut.qinit = '\A \A' aut.moore = True aut.prime_varlists() g = enum.action_to_steps(aut, env=env, sys=sys, qinit=aut.qinit) # 36 states reachable, but should enumerate fewer assert len(g) == 4, g.nodes() # these are state projections (partial assignments) # a state assigns to all variable names # (infinitely many) states = {enum._node_tuple(d, keys) for u, d in g.nodes(data=True)} assert tuple([True, 1]) in states, states r = {p for p in states if p[0] is True} assert len(r) == 2 r = {p for p in states if p[0] is False} assert len(r) == 2
def test_exist_init(): aut = symbolic.Automaton() aut.declare_variables(x=(0, 2), y='bool', z='bool') aut.varlist = dict(env={'x'}, sys={'y', 'z'}) # single initial state s = '(x = 1) /\ y /\ z' aut.init['env'] = aut.add_expr(s) aut.build() g = nx.DiGraph() fol = _init_context(aut) umap = dict() keys = ('y', 'x', 'z') queue, visited = enum._exist_init(g, aut, umap, keys) assert len(queue) == 1, queue (q, ) = queue assert q in g, (q, g) d = g.nodes[q] d_ = dict(x=1, y=True, z=True) assert d == d_, d # multiple initial states: should pick one s = '(x = 1) /\ y' aut.init['env'] = aut.add_expr(s) a = aut.build() g = nx.DiGraph() umap = dict() queue, visited = enum._exist_init(g, aut, umap, keys) assert len(queue) == 1, queue (q, ) = queue assert q in g, (q, g) d = g.nodes[q] varnames = {'x', 'y', 'z'} assert set(d) == varnames, d assert d['x'] == 1, d assert d['y'] is True, d assert isinstance(d['z'], bool), d
def test_code_generation(): aut = trl.Automaton() aut.declare_variables(x=(1, 6), y=(1, 6)) u = aut.to_bdd(" y' = (x - y) ") out_vars = ["y'"] code = dump.dumps_bdds_as_code(u, out_vars, aut) file_name = 'generated_foo.py' with open(file_name, 'w') as f: f.write(code) from generated_foo import step # load generated code state = dict(x=3, y=3) out_vars = step(state) out_vars_ = {"y'": 0} assert out_vars == out_vars_, out_vars state = dict(x=2, y=1) out_vars = step(state) out_vars_ = {"y'": 1} assert out_vars == out_vars_, out_vars state = dict(x=5, y=3) out_vars = step(state) out_vars_ = {"y'": 2} assert out_vars == out_vars_, out_vars state = dict(x=1, y=0) out_vars = step(state) out_vars_ = {"y'": 1} assert out_vars == out_vars_, out_vars
def test_cpre_mealy_circular(): cpre = fx.step aut = symbolic.Automaton() aut.declare_variables(x='bool', y='bool') aut.varlist['env'] = ['x'] aut.varlist['sys'] = ['y'] aut.moore = False aut.plus_one = False aut.build() # aut.action['env'] = aut.add_expr("x' ") aut.action['sys'] = aut.add_expr("x' ") env_action = aut.action['env'] sys_action = aut.action['sys'] target = aut.true u = cpre(env_action, sys_action, target, aut) assert u == aut.true # aut.action['env'] = aut.true aut.action['sys'] = aut.add_expr("x' ") env_action = aut.action['env'] sys_action = aut.action['sys'] target = aut.true u = cpre(env_action, sys_action, target, aut) assert u == aut.false
def test_declare_variables(): aut = trl.Automaton() aut.declare_variables(x=(0, 5), y='bool') assert 'x' in aut.vars, aut.vars assert "x'" in aut.vars, aut.vars assert 'y' in aut.vars, aut.vars assert "y'" in aut.vars, aut.vars
def test_prime_varlists(): aut = trl.Automaton() aut.varlist.update(env=['x'], sys=['y']) aut.prime_varlists() assert "env'" in aut.varlist, aut.varlist assert aut.varlist["env'"] == ["x'"], aut.varlist assert "sys'" in aut.varlist, aut.varlist assert aut.varlist["sys'"] == ["y'"], aut.varlist
def test_add_vars(): aut = trl.Automaton() aut.add_vars({'x': {'type': 'int', 'dom': (0, 5)}}, flexible=False) aut.add_vars({'y': {'type': 'bool'}}, flexible=True) assert 'x' in aut.vars, aut.vars assert "x'" not in aut.vars, aut.vars assert 'y' in aut.vars, aut.vars assert "y'" in aut.vars, aut.vars
def test_type_action_for(): aut = trl.Automaton() aut.declare_variables(x=(0, 10), y=(0, 10), z='bool') t = aut.type_action_for(['x', 'y']) t_ = ("(((0 <= x) /\ (x <= 10)) " "/\ ((0 <= x') /\ (x' <= 10))) " "/\ (((0 <= y) /\ (y <= 10)) " "/\ ((0 <= y') /\ (y' <= 10)))") assert t == t_, t
def test_replace_with_unprimed(): aut = trl.Automaton() aut.declare_variables(x=(0, 10), y=(0, 10)) aut.declare_constants(z='bool') u = aut.add_expr("(x' = 1 /\ y' = 2) \/ ~ z") vrs = ['x', 'y'] v = aut.replace_with_unprimed(vrs, u) v_ = aut.add_expr("(x = 1 /\ y = 2) \/ ~ z") assert v == v_, list(aut.pick_iter(v))
def test_implies_type_hints(): aut = trl.Automaton() aut.declare_variables(x=(0, 10), y=(0, 10), z='bool') u = aut.add_expr('x \in 0..10 /\ y \in 0..10') assert aut.implies_type_hints(u) assert aut.implies_type_hints(u, vrs=['x', 'y']) u = aut.add_expr('x \in 0..12 /\ y \in 0..10') assert not aut.implies_type_hints(u) u = aut.add_expr('y \in 0..10') assert not aut.implies_type_hints(u) assert aut.implies_type_hints(u, vrs=['y'])
def _grspec_to_automaton(g): """Return `omega.symbolic.temporal.Automaton` from `GRSpec`. @type g: `tulip.spec.form.GRSpec` @rtype: `omega.symbolic.temporal.Automaton` """ if omega is None: raise ImportError('Failed to import package `omega`.') a = trl.Automaton() d = dict(g.env_vars) d.update(g.sys_vars) for k, v in d.items(): if v in ('boolean', 'bool'): r = 'bool' elif isinstance(v, list): # string var -> integer var r = (0, len(v) - 1) elif isinstance(v, tuple): r = v else: raise ValueError('unknown variable type: {v}'.format(v=v)) d[k] = r g.str_to_int() # reverse mapping by `synth.strategy2mealy` a.declare_variables(**d) a.varlist.update(env=list(g.env_vars.keys()), sys=list(g.sys_vars.keys())) f = g._bool_int.__getitem__ a.init['env'] = " & ".join( "( %s )" % f(ei) for ei in g.env_init) if len(g.env_init) > 0 else "TRUE" a.init['sys'] = " & ".join( "( %s )" % f(si) for si in g.sys_init) if len(g.sys_init) > 0 else "TRUE" a.action['env'] = " & ".join( "( %s )" % f(es) for es in g.env_safety) if len(g.env_safety) > 0 else "TRUE" a.action['sys'] = " & ".join( "( %s )" % f(ss) for ss in g.sys_safety) if len(g.sys_safety) > 0 else "TRUE" w1 = ['!({s})'.format(s=s) for s in map(f, g.env_prog)] if len(g.env_prog) > 0 else ["FALSE"] w2 = [f(sp) for sp in g.sys_prog] if len(g.sys_prog) > 0 else ["TRUE"] a.win['<>[]'] = a.bdds_from(*w1) a.win['[]<>'] = a.bdds_from(*w2) a.moore = g.moore a.plus_one = g.plus_one a.qinit = g.qinit return a
def test_functional_synthesis(): aut = trl.Automaton() aut.declare_variables(x=(1, 10)) aut.declare_variables(y=(1, 10)) x_bits = aut.vars['x']['bitnames'] y_bits = aut.vars['y']['bitnames'] u = aut.to_bdd('x = y') outputs = fcn.make_functions(u, y_bits, aut.bdd) for x_bit, y_bit in zip(x_bits, y_bits): x_bdd = aut.bdd.add_expr(x_bit) y_bdd = outputs[y_bit]['function'] assert x_bdd == y_bdd, (x_bit, y_bit)
def test_enumerate_state_machine(): aut = symbolic.Automaton() aut.declare_variables(x='bool', y=(0, 17)) init = aut.add_expr('x /\ (y = 1)') action = aut.add_expr(''' /\ ( (x /\ (y = 1)) => (~ x' /\ (y' = 2)) ) /\ ( (~ x /\ (y = 2)) => (x' /\ (y' = 1)) ) ''') g = enum.enumerate_state_machine(init, action, aut) assert len(g) == 2, len(g) e = list(g.edges()) assert len(e) == 2, len(e)
def test_init_search(): aut = symbolic.Automaton() aut.declare_variables(x='bool') aut.varlist = dict(env=[], sys=['x']) aut.init['env'] = aut.true aut.build() g = nx.DiGraph() fol = _init_context(aut) umap = dict() keys = ['x'] qinit = '\A \E' queue, visited = enum._init_search(g, aut, umap, keys, qinit) assert len(queue) == 1, queue
def test_vars_of_players(): aut = trl.Automaton() aut.varlist.update(env=['x'], sys=['y']) vrs = aut.vars_of_players({'env'}) vrs_ = {'x'} assert vrs == vrs_, vrs vrs = aut.vars_of_players({'env', 'sys'}) vrs_ = {'x', 'y'} assert vrs == vrs_, vrs vrs = aut.vars_of_all_players assert vrs == set(), vrs aut.players.update(env=0, sys=1) vrs = aut.vars_of_all_players assert vrs == vrs_, vrs
def closed_system_to_automaton(formula): """Return `Automaton` from temporal formula `f`. @type formula: `str` describing a closed system with GR(1) liveness @rtype: `temporal.Automaton` """ aut = trl.Automaton() d = split_gr1(formula) aut.init['sys'] = _to_bdd(d['init'], aut) aut.action['sys'] = _to_bdd(d['action'], aut) aut.win['sys'] = { '<>[]': [_to_bdd([t], aut) for t in d['persistence']], '[]<>': [_to_bdd([t], aut) for t in d['recurrence']]} return aut
def graph_to_logic(g, nodevar, ignore_initial, receptive=False, self_loops=False, aut=None): """Flatten labeled graph to temporal logic formulas. @param g: `TransitionSystem` The attribute `g.owner` defines who selects the next node. The attribute `g.env_vars` determines who controls each variable. @param g: `TransitionSystem` @param nodevar: variable that stores current node @type nodevar: `str` @param ignore_initial: if `False`, then add initial condition using `g.initia_nodes`. @type ignore_initial: `bool` @param receptive: if `True`, then add assumptions to ensure receptiveness at each node. @param self_loops: if `True`, then add all self-loops @param aut: define in this automaton. If `None`, return fresh `temporal.Automaton` @return: temporal formulas representing `g`. @rtype: `temporal.Automaton` """ (env_init, env_tran, sys_init, sys_tran) = _graph_to_formulas(g, nodevar, ignore_initial, receptive=receptive, self_loops=self_loops) # package as automaton dom = _nodevar_dom(g) if aut is None: aut = trl.Automaton() d = dict(g.vars) d[nodevar] = dom aut.declare_variables(**d) aut.varlist['env'] = list(g.env_vars) aut.varlist['sys'] = [k for k in g.vars if k not in g.env_vars] aut.varlist[g.owner].append(nodevar) aut.init.update(env=_add_expr(env_init, aut), sys=_add_expr(sys_init, aut)) aut.action.update(env=_add_expr(env_tran, aut), sys=_add_expr(sys_tran, aut)) return aut
def specify_component_bar(): """Return temporal logic spec of component bar.""" aut = trl.Automaton() aut.players = ['foo', 'bar', 'scheduler'] aut.declare_variables(active=(1, 2), home=(0, 1), known_room=(0, 2), pos=(0, 2), known=(0, 1), turn=(0, 1)) aut.varlist['scheduler'] = ['turn'] aut.varlist['foo'] = ['active'] aut.varlist['bar'] = ['known_room', 'known', 'pos', 'home'] spec = r''' FooInit == active = 1 /\ turn = 1 BarInit == /\ pos = 0 /\ home = 1 /\ known_room = 0 /\ known = 0 FooNext == /\ active \in 1..2 /\ active' \in 1..2 /\ ((turn = 1) => (active' = active)) /\ (turn' != turn) UNCHANGED == /\ home' = home /\ pos' = pos /\ known' = known /\ known_room' = known_room BarNext == ((turn = 0) => (UNCHANGED)) ''' aut.define(spec) aut.init.update(foo='FooInit', bar='BarInit') aut.action.update(foo='FooNext', bar='BarNext') aut.win = dict( bar={ '<>[]': aut.bdds_from('pos = 0', 'turn = 0', 'turn = 1'), '[]<>': aut.bdds_from('pos = 1', 'pos = 2') }) aut.qinit = r'\E \A' aut.moore = True aut.plus_one = True return aut
def test_step(): aut = symbolic.Automaton() aut.declare_variables(x='bool', y='bool') aut.varlist = dict(env=['x'], sys=['y']) aut.action['env'] = aut.true aut.action['sys'] = aut.add_expr("x' => ~ y' ") aut.moore = False aut.plus_one = False aut.build() env_action = aut.action['env'] sys_action = aut.action['sys'] target = aut.add_expr('y') u = fx.step(env_action, sys_action, target, aut) assert u == aut.false, _to_expr(u, aut) aut.varlist["sys'"] = ["x'", "y'"] aut.varlist["env'"] = list() u = fx.step(env_action, sys_action, target, aut) assert u == aut.true, _to_expr(u, aut)
def test_step(): aut = trl.Automaton() aut.declare_variables(x='bool', y=(1, 3)) aut.varlist = dict(env=['x'], sys=['y']) aut.prime_varlists() aut.init['impl_sys'] = 'True' action = aut.add_expr("x /\ (~ x') /\ (y = 2) /\ (y' = 3)") aut.action['impl'] = action stepper = steps.AutomatonStepper(aut) # `action` enabled at `state` state = dict(x=True, y=2) next_values = stepper.step(state) d = dict(x=False, y=3) assert next_values == d, (next_values, d) # `action` not enabled at `state` state = dict(x=True, y=1) with nt.assert_raises(ValueError): stepper.step(state)
def test_forall_exist_init(): aut = symbolic.Automaton() aut.declare_variables(x='bool', y='bool') aut.varlist = dict(env={'x'}, sys={'y'}) # single initial state s = 'x /\ y' aut.init['env'] = aut.add_expr(s) aut.build() g = nx.DiGraph() fol = _init_context(aut) umap = dict() keys = ('x', 'y') queue, visited = enum._forall_exist_init(g, aut, umap, keys) assert len(queue) == 1, queue (q, ) = queue assert q in g, (q, g) d = g.nodes[q] d_ = dict(x=True, y=True) assert d == d_, (d, d_) # multiple initial states s = 'x <=> y' aut.init['env'] = aut.add_expr(s) aut.build() g = nx.DiGraph() umap = dict() queue, visited = enum._forall_exist_init(g, aut, umap, keys) assert len(queue) == 2, queue q0, q1 = queue assert q0 in g, (q0, g) assert q1 in g, (q1, g) d0 = g.nodes[q0] d1 = g.nodes[q1] varnames = set(keys) assert set(d0) == varnames, (d0, varnames) assert set(d1) == varnames, (d1, varnames) # \A \E: for each `x`, pick some `y` assert d0['x'] == d0['y'], d0 assert d1['x'] == d1['y'], d1 assert d0['x'] != d1['x'], (d0, d1) v = {d0['x'], d1['x']} v_ = {False, True} assert v == v_, v
def test_exist_forall_init(): aut = symbolic.Automaton() aut.declare_variables(x='bool', y='bool') aut.varlist = dict(env={'x'}, sys={'y'}) # single initial state aut.init['env'] = 'x' aut.init['sys'] = ' ~ y' a = aut.build() g = nx.DiGraph() fol = _init_context(aut) umap = dict() keys = ('x', 'y') queue, visited = enum._exist_forall_init(g, aut, umap, keys) assert len(queue) == 1, queue (q, ) = queue assert q in g, (q, g) d = g.nodes[q] d_ = dict(x=True, y=False) assert d == d_, (d, d_) # multiple initial states aut.init['env'] = 'TRUE' aut.init['sys'] = 'y' a = aut.build() g = nx.DiGraph() umap = dict() queue, visited = enum._exist_forall_init(g, aut, umap, keys) assert len(queue) == 2, queue q0, q1 = queue assert q0 in g, (q0, g) assert q1 in g, (q1, g) d0 = g.nodes[q0] d1 = g.nodes[q1] varnames = set(keys) assert set(d0) == varnames, (d0, varnames) assert set(d1) == varnames, (d1, varnames) # \E \A picks same `y` for all initial states assert d0['y'] is True, d0 assert d1['y'] is True, d1 v = {d0['x'], d1['x']} v_ = {False, True} assert v == v_, v
def gr1_specification(): """Return a temporal logic spec in the GR(1) fragment.""" aut = trl.Automaton() aut.declare_variables(x=(1, 3), y=(-3, 3)) aut.varlist.update(env=['x'], sys=['y']) aut.init['env'] = 'x = 1' aut.init['sys'] = 'y = 2' aut.action['env'] = ''' /\ x \in 1..2 /\ x' \in 1..2 ''' aut.action['sys'] = ''' /\ y \in -3..3 /\ y' = x - 3 ''' aut.win['<>[]'] = aut.bdds_from('x = 2') aut.win['[]<>'] = aut.bdds_from('y != -1') aut.qinit = '\E \A' aut.moore = True aut.plus_one = True return aut
def spec(): aut = trl.Automaton() aut.declare_variables(x=(1, 3), y=(0, 5), z='bool') aut.varlist['sys'] = ['x', 'y', 'z'] goal = aut.to_bdd('(x = 2) /\ (y = 1) /\ z') action = aut.to_bdd(''' (* type invariant *) /\ x \in 1..3 /\ y \in 0..5 /\ ((z <=> TRUE) \/ (z <=> FALSE)) (* primed type invariant *) /\ x' \in 1..3 /\ y' \in 0..5 /\ ((z' <=> TRUE) \/ (z <=> FALSE)) (* allowed changes *) /\ (x' = x + 1) /\ (y' = y - 2) /\ (z' <=> ~ z) ''') return aut, goal, action
def specify_component_bar(): """Return temporal logic spec of component bar.""" aut = trl.Automaton() aut.players = ['foo', 'bar', 'scheduler'] aut.declare_variables(x=(0, 1), y=(0, 1), turn=(0, 1)) aut.varlist['scheduler'] = ['turn'] aut.varlist['foo'] = ['x'] aut.varlist['bar'] = ['y'] spec = r''' FooInit == x = 1 /\ turn = 1 BarInit == y = 1 FooNext == /\ ((x = 1) \/ (y = 1)) /\ ((y = 0) => (x' = 1)) /\ (x \in 0..1) /\ (x' \in 0..1) /\ ((turn = 1) => (x' = x)) /\ (turn' != turn) BarNext == /\ ((x = 1) \/ (y = 1)) /\ (y \in 0..1 /\ y' \in 0..1) /\ ((turn != 1) => (y' = y)) ''' aut.define(spec) aut.init.update( foo='FooInit', bar='BarInit') aut.action.update( foo='FooNext', bar='BarNext') aut.win = dict( bar={'<>[]': aut.bdds_from('x = 0', 'turn = 0', 'turn = 1'), '[]<>': aut.bdds_from('y = 0', 'y = 1')}) aut.qinit = r'\E \A' aut.moore = True aut.plus_one = True return aut
def specify_component_foo(): """Return temporal logic spec of component foo.""" aut = trl.Automaton() aut.players = ['foo', 'bar', 'scheduler'] aut.declare_variables(active=(1, 2), home=(0, 1), known_room=(0, 2), pos=(0, 2), known=(0, 1), turn=(0, 1)) aut.varlist['scheduler'] = ['turn'] aut.varlist['foo'] = ['active'] aut.varlist['bar'] = ['known_room', 'known', 'pos', 'home'] spec = r''' FooInit == active = 1 BarInit == /\ pos = 0 /\ home = 1 /\ known_room = 1 /\ known = 1 /\ turn = 1 INV == /\ pos \in 0..2 /\ known_room \in 0..2 /\ home \in 0..1 /\ known \in 0..1 BarUNCHANGED == /\ home' = home /\ pos' = pos /\ known' = known /\ known_room' = known_room BarAction == /\ INV /\ (home = 1 => home' = 0) /\ (home = 1 <=> pos = 0) /\ (~(home = 0 /\ known' = 1) \/ home' = 1) /\ (~(home = 0 /\ pos = 1 /\ active = 1) \/ (known' = 1 /\ known_room' = 1)) /\ (~(home = 0 /\ pos = 2 /\ active = 2) \/ (known' = 1 /\ known_room' = 2)) /\ (~(home = 1 /\ known = 1 /\ known_room = 1) \/ (known' = 1 /\ known_room' = 1 /\ pos' = 1)) /\ (~(home = 1 /\ known = 1 /\ known_room = 2) \/ (known' = 1 /\ known_room' = 2 /\ pos' = 2)) /\ (~(home = 0 /\ (pos = 2 /\ active != 2)) \/ (known' = 0 /\ known_room' = 0 /\ pos' = 1)) /\ (~(home = 0 /\ (pos = 1 /\ active != 1)) \/ (known' = 0 /\ known_room' = 0 /\ pos' = 2)) FooNext == \/ ((turn = 1) /\ (active' = active)) \/ /\ (turn = 0 /\ active \in 1..2 /\ active' \in 1..2) /\ (active' = active \/ active' != active) BarNext == \/ ((turn = 1) /\ (BarAction)) \/ /\ ((turn = 0) /\ (BarUNCHANGED)) /\ (turn' = 1) ''' aut.define(spec) aut.init.update(foo='FooInit', bar='BarInit') aut.action.update(foo='FooNext', bar='BarNext') aut.win = dict( foo={ '<>[]': aut.bdds_from('turn = 0', 'turn = 1'), '[]<>': aut.bdds_from('active=1', 'active=2') }) aut.qinit = r'\E \A' aut.moore = True aut.plus_one = True return aut
from omega.games import gr1 from omega.games import enumeration as enum from omega.symbolic import temporal as trl from omega.games.enumeration import action_to_steps from omega.symbolic import enumeration as sym_enum import networkx as nx import matplotlib.pyplot as plt aut = trl.Automaton() aut.declare_variables(active=(1, 2), pos1=(-1, 2), rX1=(0, 4), rY1=(0, 4), goTo1=(0, 2)) aut.varlist['env'] = ['active'] aut.varlist['sys'] = ['rX1', 'rY1', 'goTo1', 'pos1'] aut.prime_varlists() specs = ''' envInit == /\ active = 1 envNext == /\ (active \in 1..2 /\ active' \in 1..2) /\ (active' = active \/ active' != active) rob1_init == /\ pos1 = 0 /\ goTo1 = 1
from omega.symbolic import fol from omega.symbolic import temporal aut = temporal.Automaton() aut.declare_variables(x='bool', y='bool') u = aut.add_expr('x /\ y') aut._clear_invalid_cache() aut._cache_expr('x /\ y') aut._fetch_expr(u) aut._fetch_expr(u) aut._add_expr('x') del u fol._bdd.reorder(aut.bdd) aut._add_expr('y') aut._add_expr('x \/ ~ y') assert len(aut._bdd_to_expr) == 1, aut._bdd_to_expr aut._clear_invalid_cache() assert not aut._bdd_to_expr