def test_until(): s = gr1.until_to_gr1('p', 'q', aux='c') assert isinstance(s, spec.GRSpec) assert 'aux' not in str(s) assert 'c' in s.sys_vars assert 'p' in s.sys_vars assert 'q' in s.sys_vars # []!q s0 = spec.GRSpec( sys_vars={'q'}, sys_safety={'!q'} ) assert not synth.is_realizable('gr1c', s | s0) # !q && <>q s1 = spec.GRSpec( sys_vars={'q'}, sys_init={'!q'}, sys_prog={'q'} ) assert synth.is_realizable('gr1c', s | s1) # !q && []!p && <>q s1 = spec.GRSpec( sys_vars={'q'}, sys_init={'!q'}, sys_safety={'!p'}, sys_prog={'q'} ) assert not synth.is_realizable('gr1c', s | s1)
def test_eventually(): s = gr1.eventually_to_gr1('p', aux='c') assert isinstance(s, spec.GRSpec) assert 'aux' not in str(s) assert 'c' in s.sys_vars assert 'p' in s.sys_vars s.moore = False s.plus_one = False s.qinit = '\A \E' # []!p s0 = spec.GRSpec( sys_vars={'p'}, sys_safety={'!p'}, moore=False, plus_one=False, qinit='\A \E' ) assert not synth.is_realizable(s | s0) # !p && []<>p && []<>!p s1 = spec.GRSpec( sys_vars={'p'}, sys_init={'!p'}, sys_prog={'!p', 'p'}, moore=False, plus_one=False, qinit='\A \E' ) assert synth.is_realizable(s | s1)
def multiple_env_actions_test(): """Two env players, 3 states controlled by sys. sys wins marginally, due to assumption on next combination of actions by env players. """ # 1 <---> 2 # ---> 3 env_actions = [('env_alice', transys.MathSet({'left', 'right'}) ), ('env_bob', transys.MathSet({'left', 'right'}) )] sys = transys.OpenFTS(env_actions) sys.states.add_from({'s1', 's2', 's3'}) sys.states.initial.add_from({'s1'}) sys.add_edge('s1', 's2', env_alice='left', env_bob='right') sys.add_edge('s1', 's3', env_alice='right', env_bob='left') # at state 3 sys loses sys.add_edge('s2', 's1', env_alice='left', env_bob='right') logging.debug(sys) env_safe = {'(loc = s1) -> X( (env_alice = left) && (env_bob = right) )'} sys_prog = {'loc = s1', 'loc = s2'} specs = spec.GRSpec(env_safety=env_safe, sys_prog=sys_prog) r = synth.is_realizable('gr1c', specs, sys=sys) assert(r) # slightly relax assumption specs = spec.GRSpec(sys_prog=sys_prog) r = synth.is_realizable('gr1c', specs, sys=sys) assert(not r)
def test_eventually(): s = gr1.eventually_to_gr1('p', aux='c') assert isinstance(s, spec.GRSpec) assert 'aux' not in str(s) assert 'c' in s.sys_vars assert 'p' in s.sys_vars s.moore = False s.plus_one = False s.qinit = '\A \E' # []!p s0 = spec.GRSpec( sys_vars={'p'}, sys_safety={'!p'}, moore=False, plus_one=False, qinit='\A \E' ) assert not synth.is_realizable('omega', s | s0) # !p && []<>p && []<>!p s1 = spec.GRSpec( sys_vars={'p'}, sys_init={'!p'}, sys_prog={'!p', 'p'}, moore=False, plus_one=False, qinit='\A \E' ) assert synth.is_realizable('omega', s | s1)
def test_response(): s = gr1.response_to_gr1('p', 'q') assert isinstance(s, spec.GRSpec) assert 'p' in s.sys_vars assert 'q' in s.sys_vars # p && []!q s0 = spec.GRSpec(sys_vars={'p', 'q'}, sys_init={'p'}, sys_safety={'!q'}) assert not synth.is_realizable('gr1c', s | s0) # []!p && []!q s1 = spec.GRSpec(sys_vars={'p', 'q'}, sys_safety={'!p && !q'}) assert synth.is_realizable('gr1c', s | s1) # p && q s2 = spec.GRSpec( sys_vars={'p', 'q'}, sys_init={'p && q'}, ) assert synth.is_realizable('gr1c', s | s2) # alternating p, alternating q s3 = spec.GRSpec( sys_vars={'p', 'q'}, sys_safety={'p -> X !p', '!p -> X p', 'p -> X q', 'q -> X ! q'}) assert synth.is_realizable('gr1c', s | s3)
def test_stability(): s = gr1.stability_to_gr1('p', aux='a') assert isinstance(s, spec.GRSpec) assert 'aux' not in s.sys_vars assert 'a' in s.sys_vars assert 'p' in s.sys_vars s.moore = False s.plus_one = False s.qinit = r'\A \E' # p && X[]!p s0 = spec.GRSpec(sys_vars={'p'}, sys_init={'p'}, sys_safety={'p -> X !p', '!p -> X !p'}, moore=False, plus_one=False, qinit=r'\A \E') assert not synth.is_realizable(s | s0) # !p && X[]p s1 = spec.GRSpec(sys_vars={'p'}, sys_init={'!p'}, sys_safety={'!p -> X p', 'p -> X p'}, moore=False, plus_one=False, qinit=r'\A \E') assert synth.is_realizable(s | s1) # []<>p && []<>!p s2 = spec.GRSpec(sys_vars={'p'}, sys_prog={'p', '!p'}, moore=False, plus_one=False, qinit=r'\A \E') assert not synth.is_realizable(s | s2) # env b can prevent !p, but has tp <> become !b, # releasing sys to set p # # env: b && []<>!b # sys: !p && []((b && !p) -> X!p) s3 = spec.GRSpec(env_vars={'b'}, env_init={'b'}, env_prog={'!b'}, sys_vars={'p'}, sys_init={'!p'}, sys_safety={'(b && !p) -> X !p'}, moore=False, plus_one=False, qinit=r'\A \E') assert synth.is_realizable(s | s3) s3.env_prog = [] assert not synth.is_realizable(s | s3)
def test_response(): s = gr1.response_to_gr1('p', 'q') assert isinstance(s, spec.GRSpec) assert 'p' in s.sys_vars assert 'q' in s.sys_vars s.moore = False s.plus_one = False s.qinit = '\A \E' # p && []!q s0 = spec.GRSpec( sys_vars={'p', 'q'}, sys_init={'p'}, sys_safety={'!q'}, moore=False, plus_one=False, qinit='\A \E' ) assert not synth.is_realizable(s | s0) # []!p && []!q s1 = spec.GRSpec( sys_vars={'p', 'q'}, sys_safety={'!p && !q'}, moore=False, plus_one=False, qinit='\A \E' ) assert synth.is_realizable(s | s1) # p && q s2 = spec.GRSpec( sys_vars={'p', 'q'}, sys_init={'p && q'}, moore=False, plus_one=False, qinit='\A \E' ) assert synth.is_realizable(s | s2) # alternating p, alternating q s3 = spec.GRSpec( sys_vars={'p', 'q'}, sys_safety={ 'p -> X !p', '!p -> X p', 'p -> X q', 'q -> X ! q'}, moore=False, plus_one=False, qinit='\A \E' ) assert synth.is_realizable(s | s3)
def test_response(): s = gr1.response_to_gr1('p', 'q') assert isinstance(s, spec.GRSpec) assert 'p' in s.sys_vars assert 'q' in s.sys_vars s.moore = False s.plus_one = False s.qinit = '\A \E' # p && []!q s0 = spec.GRSpec( sys_vars={'p', 'q'}, sys_init={'p'}, sys_safety={'!q'}, moore=False, plus_one=False, qinit='\A \E' ) assert not synth.is_realizable('omega', s | s0) # []!p && []!q s1 = spec.GRSpec( sys_vars={'p', 'q'}, sys_safety={'!p && !q'}, moore=False, plus_one=False, qinit='\A \E' ) assert synth.is_realizable('omega', s | s1) # p && q s2 = spec.GRSpec( sys_vars={'p', 'q'}, sys_init={'p && q'}, moore=False, plus_one=False, qinit='\A \E' ) assert synth.is_realizable('omega', s | s2) # alternating p, alternating q s3 = spec.GRSpec( sys_vars={'p', 'q'}, sys_safety={ 'p -> X !p', '!p -> X p', 'p -> X q', 'q -> X ! q'}, moore=False, plus_one=False, qinit='\A \E' ) assert synth.is_realizable('omega', s | s3)
def multiple_env_actions_check(solver='omega'): """Two env players, 3 states controlled by sys. sys wins marginally, due to assumption on next combination of actions by env players. """ # 1 <---> 2 # 1 ---> 3 env_actions = [ { 'name': 'env_alice', 'values': transys.MathSet({'left', 'right'}) }, { 'name': 'env_bob', 'values': transys.MathSet({'bleft', 'bright'}) } ] sys = transys.FTS(env_actions) sys.states.add_from({'s1', 's2', 's3'}) sys.states.initial.add_from({'s1'}) sys.add_edge('s1', 's2', env_alice='left', env_bob='bright') sys.add_edge('s2', 's1', env_alice='left', env_bob='bright') # at state 3 sys loses sys.add_edge('s1', 's3', env_alice='right', env_bob='bleft') logging.debug(sys) env_safe = {('(loc = "s1") -> X( (env_alice = "left") && ' '(env_bob = "bright") )')} sys_prog = {'loc = "s1"', 'loc = "s2"'} specs = spec.GRSpec( env_safety=env_safe, sys_prog=sys_prog, moore=False, plus_one=False, qinit='\A \E') r = synth.is_realizable(specs, sys=sys, solver=solver) assert r # slightly relax assumption specs = spec.GRSpec( sys_prog=sys_prog, moore=False, plus_one=False, qinit='\A \E') r = synth.is_realizable(specs, sys=sys, solver=solver) assert not r
def test_eventually(): s = gr1.eventually_to_gr1('p', aux='c') assert isinstance(s, spec.GRSpec) assert 'aux' not in str(s) assert 'c' in s.sys_vars assert 'p' in s.sys_vars # []!p s0 = spec.GRSpec(sys_vars={'p'}, sys_safety={'!p'}) assert not synth.is_realizable('gr1c', s | s0) # !p && []<>p && []<>!p s1 = spec.GRSpec(sys_vars={'p'}, sys_init={'!p'}, sys_prog={'!p', 'p'}) assert synth.is_realizable('gr1c', s | s1)
def test_only_mode_control(): """Unrealizable due to non-determinism. Switched system with 2 modes: 'left', 'right'. Modes are controlled by the system. States are controlled by the environment. So only control over dynamics is through mode switching. Transitions are thus interpreted as non-deterministic. This can model uncertain outcomes in the real world, e.g., due to low quality actuators or bad low-level feedback controllers. """ # Create a finite transition system env_sws = transys.FTS() env_sws.owner = 'env' env_sws.sys_actions.add_from({'right', 'left'}) # str states n = 4 states = transys.prepend_with(range(n), 's') env_sws.atomic_propositions.add_from(['home', 'lot']) # label TS with APs ap_labels = [set(), set(), {'home'}, {'lot'}] for i, label in enumerate(ap_labels): state = 's' + str(i) env_sws.states.add(state, ap=label) # mode1 transitions transmat1 = np.array([[0, 1, 0, 1], [0, 1, 0, 0], [0, 1, 0, 1], [0, 0, 0, 1]]) env_sws.transitions.add_adj(sp.lil_matrix(transmat1), states, {'sys_actions': 'right'}) # mode2 transitions transmat2 = np.array([[1, 0, 0, 0], [1, 0, 1, 0], [0, 0, 1, 0], [1, 0, 1, 0]]) env_sws.transitions.add_adj(sp.lil_matrix(transmat2), states, {'sys_actions': 'left'}) env_vars = {'park'} env_init = {'eloc = "s0"', 'park'} env_prog = {'!park'} env_safe = set() sys_vars = {'X0reach'} sys_init = {'X0reach'} sys_prog = {'home'} sys_safe = {'next(X0reach) <-> lot || (X0reach && !park)'} sys_prog |= {'X0reach'} specs = spec.GRSpec(env_vars, sys_vars, env_init, sys_init, env_safe, sys_safe, env_prog, sys_prog) r = synth.is_realizable('gr1c', specs, env=env_sws, ignore_env_init=True) assert not r
def test_stability(): s = gr1.stability_to_gr1('p', aux='a') assert isinstance(s, spec.GRSpec) assert 'aux' not in s.sys_vars assert 'a' in s.sys_vars assert 'p' in s.sys_vars # p && X[]!p s0 = spec.GRSpec( sys_vars={'p'}, sys_init={'p'}, sys_safety={'p -> X !p', '!p -> X !p'} ) assert not synth.is_realizable('gr1c', s | s0) # !p && X[]p s1 = spec.GRSpec( sys_vars={'p'}, sys_init={'!p'}, sys_safety={'!p -> X p', 'p -> X p'} ) assert synth.is_realizable('gr1c', s | s1) # []<>p && []<>!p s2 = spec.GRSpec( sys_vars={'p'}, sys_prog={'p', '!p'} ) assert not synth.is_realizable('gr1c', s | s2) # env b can prevent !p, but has tp <> become !b, # releasing sys to set p # # env: b && []<>!b # sys: !p && []((b && !p) -> X!p) s3 = spec.GRSpec( env_vars={'b'}, env_init={'b'}, env_prog={'!b'}, sys_vars={'p'}, sys_init={'!p'}, sys_safety={'(b && !p) -> X !p'}) assert synth.is_realizable('gr1c', s | s3) s3.env_prog = [] assert not synth.is_realizable('gr1c', s | s3)
def test_until(): s = gr1.until_to_gr1('p', 'q', aux='c') assert isinstance(s, spec.GRSpec) assert 'aux' not in str(s) assert 'c' in s.sys_vars assert 'p' in s.sys_vars assert 'q' in s.sys_vars s.moore = False s.plus_one = False s.qinit = '\A \E' # []!q s0 = spec.GRSpec( sys_vars={'q'}, sys_safety={'!q'}, moore=False, plus_one=False, qinit='\A \E' ) assert not synth.is_realizable(s | s0) # !q && <>q s1 = spec.GRSpec( sys_vars={'q'}, sys_init={'!q'}, sys_prog={'q'}, moore=False, plus_one=False, qinit='\A \E' ) assert synth.is_realizable(s | s1) # !q && []!p && <>q s1 = spec.GRSpec( sys_vars={'q'}, sys_init={'!q'}, sys_safety={'!p'}, sys_prog={'q'}, moore=False, plus_one=False, qinit='\A \E' ) assert not synth.is_realizable(s | s1)
def test_until(): s = gr1.until_to_gr1('p', 'q', aux='c') assert isinstance(s, spec.GRSpec) assert 'aux' not in str(s) assert 'c' in s.sys_vars assert 'p' in s.sys_vars assert 'q' in s.sys_vars s.moore = False s.plus_one = False s.qinit = '\A \E' # []!q s0 = spec.GRSpec( sys_vars={'q'}, sys_safety={'!q'}, moore=False, plus_one=False, qinit='\A \E' ) assert not synth.is_realizable('omega', s | s0) # !q && <>q s1 = spec.GRSpec( sys_vars={'q'}, sys_init={'!q'}, sys_prog={'q'}, moore=False, plus_one=False, qinit='\A \E' ) assert synth.is_realizable('omega', s | s1) # !q && []!p && <>q s1 = spec.GRSpec( sys_vars={'q'}, sys_init={'!q'}, sys_safety={'!p'}, sys_prog={'q'}, moore=False, plus_one=False, qinit='\A \E' ) assert not synth.is_realizable('omega', s | s1)
def add_trolls_test(): G = gw.unoccupied((3, 5)) G.init_list = [(0, 0)] G.goal_list = [(0, 4)] spc = gw.add_trolls(G, [((2, 2), 1)], get_moves_lists=False) spc.moore = False spc.plus_one = False spc.qinit = r'\A \E' assert is_realizable(spc)
def add_trolls_test(): G = gw.unoccupied((3, 5)) G.init_list = [(0, 0)] G.goal_list = [(0, 4)] spc = gw.add_trolls(G, [((2, 2), 1)], get_moves_lists=False) spc.moore = False spc.plus_one = False spc.qinit = r'\A \E' assert is_realizable('omega', spc)
def test_eventually(): s = gr1.eventually_to_gr1('p', aux='c') assert isinstance(s, spec.GRSpec) assert 'aux' not in str(s) assert 'c' in s.sys_vars assert 'p' in s.sys_vars # []!p s0 = spec.GRSpec( sys_vars={'p'}, sys_safety={'!p'} ) assert not synth.is_realizable('gr1c', s | s0) # !p && []<>p && []<>!p s1 = spec.GRSpec( sys_vars={'p'}, sys_init={'!p'}, sys_prog={'!p', 'p'} ) assert synth.is_realizable('gr1c', s | s1)
def test_until(): s = gr1.until_to_gr1('p', 'q', aux='c') assert isinstance(s, spec.GRSpec) assert 'aux' not in str(s) assert 'c' in s.sys_vars assert 'p' in s.sys_vars assert 'q' in s.sys_vars # []!q s0 = spec.GRSpec(sys_vars={'q'}, sys_safety={'!q'}) assert not synth.is_realizable('gr1c', s | s0) # !q && <>q s1 = spec.GRSpec(sys_vars={'q'}, sys_init={'!q'}, sys_prog={'q'}) assert synth.is_realizable('gr1c', s | s1) # !q && []!p && <>q s1 = spec.GRSpec(sys_vars={'q'}, sys_init={'!q'}, sys_safety={'!p'}, sys_prog={'q'}) assert not synth.is_realizable('gr1c', s | s1)
def test_response(): s = gr1.response_to_gr1('p', 'q') assert isinstance(s, spec.GRSpec) assert 'p' in s.sys_vars assert 'q' in s.sys_vars # p && []!q s0 = spec.GRSpec( sys_vars={'p', 'q'}, sys_init={'p'}, sys_safety={'!q'} ) assert not synth.is_realizable('gr1c', s | s0) # []!p && []!q s1 = spec.GRSpec( sys_vars={'p', 'q'}, sys_safety={'!p && !q'} ) assert synth.is_realizable('gr1c', s | s1) # p && q s2 = spec.GRSpec( sys_vars={'p', 'q'}, sys_init={'p && q'}, ) assert synth.is_realizable('gr1c', s | s2) # alternating p, alternating q s3 = spec.GRSpec( sys_vars={'p', 'q'}, sys_safety={ 'p -> X !p', '!p -> X p', 'p -> X q', 'q -> X ! q' } ) assert synth.is_realizable('gr1c', s | s3)
import sys import tulip.gridworld as gw from tulip import synth if len(sys.argv) > 3 or "-h" in sys.argv: print("Usage: solverand.py [H W]") sys.exit(1) if len(sys.argv) >= 3: (height, width) = (int(sys.argv[1]), int(sys.argv[2])) else: (height, width) = (5, 10) Z = gw.random_world((height, width), wall_density=0.2, num_init=1, num_goals=2) print(Z) spc = Z.spec() spc.moore = False spc.qinit = r'\A \E' if not synth.is_realizable('omega', spc): print("Not realizable.") else: ctrl = synth.synthesize('omega', spc) if not ctrl.save('ctrl-solverand.svg'): print(ctrl)
def test_spec_realizable(self): spec = self.X.spec() spec.moore = False spec.plus_one = False spec.qinit = r'\A \E' assert is_realizable('omega', spec)
# If the sticks are depleted during the next step, # then it should not be caused by player 1's turn. "(sticks > 0 && sticks' = 0) -> !(player_turn = 1)" } logging.basicConfig(level=logging.WARNING) # Create the specification specs = spec.GRSpec(env_vars, sys_vars, env_init, sys_init, env_safe, sys_safe) specs.qinit = '\E \A' specs.moore = True specs.plus_one = False # Synthesize the built in TuLiP way. print(synth.is_realizable(specs, ignore_sys_init=False, ignore_env_init=False)) ctrl = synth.synthesize(specs, ignore_sys_init=False, ignore_env_init=False) assert ctrl is not None, 'unrealizable' with open('two_players_controller.pickle', 'wb') as f: pickle.dump(ctrl, f) # Save the controller as a picture. The initial transitions will cover more # than specified. if not ctrl.save('two_players.eps'): print(ctrl) # Synthesize manually by copying from TuLiP source code. # Also force to use cudd. ignore_env_init = False ignore_sys_init = False
$ ./solverand.py 3 5 """ from __future__ import print_function import sys import tulip.gridworld as gw from tulip import synth if len(sys.argv) > 3 or "-h" in sys.argv: print("Usage: solverand.py [H W]") sys.exit(1) if len(sys.argv) >= 3: (height, width) = (int(sys.argv[1]), int(sys.argv[2])) else: (height, width) = (5, 10) Z = gw.random_world((height, width), wall_density=0.2, num_init=1, num_goals=2) print(Z) spc = Z.spec() spc.moore = False spc.qinit = r'\A \E' if not synth.is_realizable(spc, solver='omega'): print("Not realizable.") else: ctrl = synth.synthesize(spc, solver='omega') if not ctrl.save('ctrl-solverand.svg'): print(ctrl)
def test_only_mode_control(): """Unrealizable due to non-determinism. Switched system with 2 modes: 'left', 'right'. Modes are controlled by the system. States are controlled by the environment. So only control over dynamics is through mode switching. Transitions are thus interpreted as non-deterministic. This can model uncertain outcomes in the real world, e.g., due to low quality actuators or bad low-level feedback controllers. """ # Create a finite transition system env_sws = transys.OpenFTS() env_sws.sys_actions.add_from({'right','left'}) # str states n = 4 states = transys.prepend_with(range(n), 's') env_sws.atomic_propositions.add_from(['home','lot']) # label TS with APs ap_labels = [set(),set(),{'home'},{'lot'}] for i, label in enumerate(ap_labels): state = 's' + str(i) env_sws.states.add(state, ap=label) # mode1 transitions transmat1 = np.array([[0,1,0,1], [0,1,0,0], [0,1,0,1], [0,0,0,1]]) env_sws.transitions.add_adj( sp.lil_matrix(transmat1), states, {'sys_actions':'right'} ) # mode2 transitions transmat2 = np.array([[1,0,0,0], [1,0,1,0], [0,0,1,0], [1,0,1,0]]) env_sws.transitions.add_adj( sp.lil_matrix(transmat2), states, {'sys_actions':'left'} ) env_vars = {'park'} env_init = {'eloc = 0', 'park'} env_prog = {'!park'} env_safe = set() sys_vars = {'X0reach'} sys_init = {'X0reach'} sys_prog = {'home'} sys_safe = {'next(X0reach) <-> lot || (X0reach && !park)'} sys_prog |= {'X0reach'} specs = spec.GRSpec(env_vars, sys_vars, env_init, sys_init, env_safe, sys_safe, env_prog, sys_prog) r = synth.is_realizable('gr1c', specs, env=env_sws, ignore_env_init=True) assert(not r)
def test_spec_realizable(self): spec = self.X.spec() spec.moore = False spec.plus_one = False spec.qinit = r'\A \E' assert is_realizable(spec)
import sys import tulip.gridworld as gw from tulip import synth if len(sys.argv) > 3 or "-h" in sys.argv: print("Usage: solverand.py [H W]") sys.exit(1) if len(sys.argv) >= 3: (height, width) = (int(sys.argv[1]), int(sys.argv[2])) else: (height, width) = (5, 10) Z = gw.random_world((height, width), wall_density=0.2, num_init=1, num_goals=2) print(Z) spc = Z.spec() spc.moore = False spc.qinit = r'\A \E' if not synth.is_realizable(spc, solver='omega'): print("Not realizable.") else: ctrl = synth.synthesize(spc, solver='omega') if not ctrl.save('ctrl-solverand.svg'): print(ctrl)
def test_spec_realizable_bool(self): spec = self.X.spec(nonbool=False) spec.moore = False spec.plus_one = False spec.qinit = r'\A \E' assert is_realizable(spec)