def create_controller(self): self.handle_init_system() self.handle_static_obstacles() self.handle_allowed_moves() self.follow_targets() #self.no_collision() specs = spec.GRSpec({} ,self.sys_vars,set() , self.sys_init , set() , self.sys_safe , set() , self.sys_prog) #print specs.pretty() specs.moore = True specs.qinit = '\E \A' ctrl = synth.synthesize('gr1c' , specs) assert ctrl is not None, 'Unrealizable' dumpsmach.write_python_case(self.controller_name+'_controller.py', ctrl, classname=self.controller_name+'Controller')
def construct_controllers(Ncar, Vlow, Vhigh, xped, vcar, xcross_start): # Simple example of pedestrian crossing street: Nped = Ncar - xcross_start + 1 xcar = 1 assert (Nped + xcross_start - 1 <= Ncar) # When a pedestrian is observed: env_vars, sys_vars, env_init, sys_init, env_safe, sys_safe, env_prog, sys_prog = pedestrianK( Ncar, Nped, xcar, vcar, Vlow, Vhigh, xped, xcross_start) Kped = design_C(env_vars, sys_vars, env_init, sys_init, env_safe, sys_safe, env_prog, sys_prog) write_python_case("ped_controller.py", Kped) # When something other than a pedestrian is observed: env_vars, sys_vars, env_init, sys_init, env_safe, sys_safe, env_prog, sys_prog = not_pedestrianK( Ncar, Nped, xcar, vcar, Vlow, Vhigh, xped, xcross_start) Knot_ped = design_C(env_vars, sys_vars, env_init, sys_init, env_safe, sys_safe, env_prog, sys_prog) write_python_case("not_ped_controller.py", Knot_ped) # When nothing is observed: env_vars, sys_vars, env_init, sys_init, env_safe, sys_safe, env_prog, sys_prog = emptyK( Ncar, Nped, xcar, vcar, Vlow, Vhigh, xped, xcross_start) Kempty = design_C(env_vars, sys_vars, env_init, sys_init, env_safe, sys_safe, env_prog, sys_prog) write_python_case("empty_controller.py", Kempty) K = dict() K["ped"] = Kped K["obj"] = Knot_ped K["empty"] = Kempty return K
def print_counterexamples( ctrl, prefix='/tmp/'): ce_list = cs_to_ce(ctrl) for index,item in enumerate(ce_list): filename = prefix + 'counterexample_' + str(index) + '.jpg'; if not item.save(filename): print(item) # print(ctrl); if not ctrl.save(prefix + 'counterstrategy.jpg'): print(ctrl) else: print('Counterstrategy pictorial representation saved in ' + prefix + 'counterstrategy.jpg'); # Create Python code for the Mealy dumpsmach.write_python_case( prefix + 'counterstrategy.py',ctrl) print('Counterstratagy implementation saved in ' + prefix + 'counterstrategy.py');
def tulip_synthesis(self): # call Tulip to synthesize a discrete controller sys = transys.FTS() sys.states.add_from(self.free_space.keys()) idx = self.determine_discrete_state() sys.states.initial.add(idx) for node in self.discrete_graph.edges.keys(): sys.transitions.add_comb(set([node]), set(self.discrete_graph.edges[node])) sys.atomic_propositions.add_from(set(self.ap.keys())) for state in self.label.keys(): sys.states.add(state,ap=set(self.label[state])) ctrl = synth.synthesize(self.Tulip_spec, sys=sys) if ctrl is None: pdb.set_trace() else: dumpsmach.write_python_case("discrete_ctrl.py", ctrl, classname="symb_ctrl") from discrete_ctrl import symb_ctrl self.discrete_controller = symb_ctrl() self.prior_discrete_graph = self.discrete_graph.copy() self.prior_label = self.label.copy()
'((signal && notclear)->X(signal)) && ((intersection && notclear)-> X(intersection)) && ((signal && red)->X(signal)) && (goal -> X(goal))' } #((intersection && notclear)-> X(intersection)) && #sys_prog |= {'X0reach'} # Create the specification specs = spec.GRSpec(env_vars, sys_vars, env_init, sys_init, env_safe, sys_safe, env_prog, sys_prog) specs.moore = True # synthesizer should find initial system values that satisfy # `env_init /\ sys_init` and work, for every environment variable # initial values that satisfy `env_init`. specs.qinit = '\E \A' ctrl = synth.synthesize(specs, sys=sys) assert ctrl is not None, 'unrealizable' # @synthesize_end@ # # Generate a graphical representation of the controller for viewing, # or a textual representation if pydot is missing. # # @plot_print@ if not ctrl.save('intersection_signal.png'): print(ctrl) # @plot_print_end@ # appended as in documentation chapter 6 dumpsmach.write_python_case("intersection_signal_fsm.py", ctrl, classname="ExampleFSM")
elif (iter1 % dim == 0) & (iter1 / dim != 0) & (iter1 / dim != dim-1): sys_safe |= {('(loc='+str(iter1)+') -> X ((loc='+str(iter1)+') || (loc ='+str(iter1+1)+') || (loc='+str(iter1-dim)+') || (loc='+str(iter1+dim)+'))')} elif (iter1 % dim == dim-1) & (iter1 / dim != 0) & (iter1 / dim != dim-1): sys_safe |= {('(loc='+str(iter1)+') -> X ((loc='+str(iter1)+') || (loc ='+str(iter1-1)+') || (loc='+str(iter1-dim)+') || (loc='+str(iter1+dim)+'))')} elif (iter1 % dim != 0) & (iter1 % dim != dim-1) & (iter1 / dim == 0): sys_safe |= {('(loc='+str(iter1)+') -> X ((loc='+str(iter1)+') || (loc ='+str(iter1-1)+') || (loc='+str(iter1+1)+') || (loc='+str(iter1+dim)+'))')} elif (iter1 % dim != 0) & (iter1 % dim != dim-1) & (iter1 / dim == dim-1): sys_safe |= {('(loc='+str(iter1)+') -> X ((loc='+str(iter1)+') || (loc ='+str(iter1-1)+') || (loc='+str(iter1-dim)+') || (loc='+str(iter1+1)+'))')} elif iter1 == 0: sys_safe |= {('(loc='+str(iter1)+') -> X ((loc='+str(iter1)+') || (loc ='+str(iter1+1)+') || (loc='+str(iter1+dim)+'))')} elif iter1 == dim-1: sys_safe |= {('(loc='+str(iter1)+') -> X ((loc='+str(iter1)+') || (loc ='+str(iter1-1)+') || (loc='+str(iter1+dim)+'))')} elif iter1 == dim*(dim-1): sys_safe |= {('(loc='+str(iter1)+') -> X ((loc='+str(iter1)+') || (loc ='+str(iter1+1)+') || (loc='+str(iter1-dim)+'))')} elif iter1 == dim*dim-1: sys_safe |= {('(loc='+str(iter1)+') -> X ((loc='+str(iter1)+') || (loc ='+str(iter1-1)+') || (loc='+str(iter1-dim)+'))')} #The system robot should never collide with either environment robots for iter1 in range(dim): #sys_safe |= {('!(env2 = '+str(iter1)+') || !(loc = '+str(iter1+dim)+')')} sys_safe |= {('(loc = '+str(iter1+dim)+') -> X(!(env2 = '+str(iter1)+'))')} sys_safe |= {('!(loc = '+str(iter1+(3*dim))+')')} sys_prog = set() sys_prog |= {'stage = 2'} specs = spec.GRSpec(env_vars, sys_vars, env_init, sys_init, env_safe, sys_safe, env_prog, sys_prog) ctrl = synth.synthesize('gr1c', specs) dumpsmach.write_python_case("democontroller1.py", ctrl, classname="ExampleCtrl") #pickle.dump(ctrl, open("pro3_1_ctrl.pkl", "wb"), pickle.HIGHEST_PROTOCOL) print specs.pretty()
'! ( (loc1 = ' + str(iter1) + ') && (loc2 = ' + str(iter1) + ') )' } specs = spec.GRSpec(env_vars, sys_vars, env_init, sys_init, env_safe, sys_safe, env_prog, sys_prog) #GR(1) specification created #print specs.pretty() # # Controller synthesis # # The controller decides based on current variable values only, # without knowing yet the next values that environment variables take. # A controller with this information flow is known as Moore. specs.moore = True # Ask the synthesizer to find initial values for system variables # that, for each initial values that environment variables can # take and satisfy `env_init`, the initial state satisfies # `env_init /\ sys_init`. specs.qinit = '\E \A' # i.e., "there exist sys_vars: forall sys_vars" #assert not specs.sys_safe ctrl = synth.synthesize('gr1c', specs) assert ctrl is not None, 'unrealizable' print ctrl #print ctrl #if not ctrl.save('gr1.png'): # print(ctrl) #print ctrl #print specs.pretty() dumpsmach.write_python_case("sys3_controller.py", ctrl, classname="NoEnvController")
# @specs_create_section_end@ # # Controller synthesis # # At this point we can synthesize the controller using one of the available # methods. # # @synthesize@ # Moore machines # controller reads `env_vars, sys_vars`, but not next `env_vars` values specs.moore = False # synthesizer should find initial system values that satisfy # `env_init /\ sys_init` and work, for every environment variable # initial values that satisfy `env_init`. specs.qinit = '\E \A' ctrl = synth.synthesize(specs, sys=sys_water) assert ctrl is not None, 'unrealizable' # @synthesize_end@ # # Generate a graphical representation of the controller for viewing, # or a textual representation if pydot is missing. # # @plot_print@ if not ctrl.save('discrete.png'): print(ctrl) # @plot_print_end@ Filename = 'WaterControl_controller.py' dumpsmach.write_python_case(Filename, ctrl)
def runPaperExample(exampleRun, ver="1", riskgt=17, energygt=0): # set initial variables if exampleRun == "test1": ver = "1" riskgt = 17 energygt = 0 elif exampleRun == "test2": ver = "2" riskgt = 17 energygt = 6 elif exampleRun == "test3": ver = "3" riskgt = 16 energygt = 6 # set logfile import logging logging.basicConfig( filename="deliberative_action_planner_%s.log" % ver, level=logging.INFO, filemode="w" ) # level=logging.DEBUG logger = logging.getLogger(__name__) # Create a finite transition system sys_sws = transys.FTS() # system actions only, no (open) env. yet # add the states and actions # sys_sws.states.add_from(['s1','s2','s3','s4','s5']) for i in range(1, 5 + 1): sys_sws.states.add("s" + str(i)) # sys_sws.actions.add_from(['a12_1','a12_2','a23_1', 'a23_2', 'a15_1', 'a15_2', 'a14_1', 'a45_1', 'a35_1']) # then set up the transitions (state1, action1 -> state2) for numlist in [[1, 2, 2], [2, 3, 2], [1, 5, 2], [1, 4, 1], [4, 5, 1], [3, 5, 1]]: st1 = numlist[0] # [s"#1" loc1, s"#2" loc2, number of actions a"#1#2_#"] st2 = numlist[1] numactions = numlist[2] st1str = "s" + str(st1) st2str = "s" + str(st2) # sys_sws.states.add_from([st1str,st2str]) # could do this instead of above for i in range(1, numactions + 1): astr = "a" + str(st1) + str(st2) + "_" + str(i) sys_sws.actions.add(astr) # could do this instead of above sys_sws.transitions.add(st1str, st2str, actions=astr) sys_sws.transitions.add(st2str, st1str, actions=astr) # then set up transitions for (state1, wait -> state1) sys_sws.actions.add("wait") for st1 in range(1, 5 + 1): st1str = "s" + str(st1) sys_sws.transitions.add(st1str, st1str, actions="wait") # set s1 as initial state initial_state_str = "s1" # initial_state_str = 's2' sys_sws.states.initial.add(initial_state_str) # This is what is visible to the outside world (and will go into synthesis method) print(sys_sws) # show the Finite Transition System, make sure it was encoded properly sys_sws.save("deliberative_%sa.pdf" % ver) # save the visual diagram of the FTS, for same reason # sys_sws.save() shows all possible transitions between states according to actions print("Done saving deliberative_%sa.pdf" % ver) # # Environment variables and specification # # The environment can issue a park signal that the robot just respond # to by moving to the lower left corner of the grid. We assume that # the park signal is turned off infinitely often. # env_vars = set() # empty set env_init = set() # empty set env_prog = set() # empty set env_safe = set() # empty set # # System specification # # The system specification is that the robot should (repeatedly?) revisit # the rightmost spire (this is because there are no 'wait' or 'stay in same # state' actions currently). # does sys_vars actually use the "0" value? it doesn't seem to... # basically, looks like a "0" value pulls the value completely off the stack (as False?), in the 'atomic proposition' sense of things # so, we want to avoid using value=0 for this kind of stuff! ^_^ # note: for gr1c, lower bound must be zero (0) print("Writing up goals and such for system") print("Writing up sys vars and such for system") sys_vars = dict() sys_init = set() sys_prog = set() sys_safe = set() sys_init |= {"sys_actions=wait"} # start in wait mode goalstr = "s5" # goalstr = 's3' sys_prog |= {"loc=%s" % goalstr} # goal --> []<> (get to s5) sys_safe |= { "loc=%s -> next(loc=%s)" % (goalstr, goalstr) } # then stay there forever # this didn't seem to work with the FTS before, now does for some reason, not sure what's going on... energylo = 0 energyhi = 20 sys_vars.update({"energy": (energylo, energyhi)}) sys_init |= {"energy=%d" % energyhi} sys_safe |= {"energy > %d" % energygt} # must keep fuel/energy usage above energygt risklo = 0 riskhi = 20 sys_vars.update({"risk": (risklo, riskhi)}) sys_init |= {"risk=%d" % riskhi} sys_safe |= {"risk > %d" % riskgt} # must keep risk usage above riskgt # 0 1 2 3 4 5 6 7 8 9 allactStr = ["a35_1", "a23_1", "a23_2", "a12_1", "a12_2", "a15_2", "a15_1", "a45_1", "a14_1", "wait"] alldropenergy = [4, 3, 6, 2, 3, 7, 6, 5, 3, 0] alldroprisk = [1, 4, 0, 2, 1, 1, 2, 0, 0, 0] for actStr, energydrop, riskdrop in zip(allactStr, alldropenergy, alldroprisk): # energystr = energyStr(energylo,energyhi,energydrop) energystr = dropStr("energy", energylo, energyhi, energydrop) sys_safe |= { "sys_actions=%s -> (%s && (X(energy=0) <-> energy<=%d))" % (actStr, energystr, alldropenergy[i - 1]) } # wait action keeps energy at same level (no energy used) riskstr = dropStr("risk", risklo, riskhi, riskdrop) sys_safe |= { "sys_actions=%s -> (%s && (X(risk=0) <-> risk<=%d))" % (actStr, riskstr, alldroprisk[i - 1]) } # wait action keeps energy at same level (no energy used) # 0 1 2 3 4 # atakepicture# alldropenergy2 = [0, 0, 0, 0, 0] alldroprisk2 = [0, 0, 0, 0, 0] for i in range(1, 5 + 1): # [1] atakepicture1,picAtS1Taken, ... actStr = "atakepicture%d" % i energystr = dropStr("energy", energylo, energyhi, alldropenergy2[i - 1]) sys_safe |= { "sys_actions=%s -> (%s && (X(energy=0) <-> energy<=%d))" % (actStr, energystr, alldropenergy2[i - 1]) } # wait action keeps energy at same level (no energy used) riskstr = dropStr("risk", risklo, riskhi, alldroprisk2[i - 1]) sys_safe |= { "sys_actions=%s -> (%s && (X(risk=0) <-> risk<=%d))" % (actStr, riskstr, alldroprisk2[i - 1]) } # wait action keeps energy at same level (no energy used) actboolStr = "picAtS%dTaken" % i locStr = "s%d" % i sys_sws.actions.add(actStr) sys_sws.transitions.add("s%d" % i, "s%d" % i, actions=actStr) sys_vars.update({actboolStr: "boolean"}) sys_init |= {"!%s" % actboolStr} sys_safe |= { "(energy>%d && loc=%s && sys_actions=%s) -> X(%s)" % (alldropenergy2[i - 1], locStr, actStr, actboolStr) } sys_safe |= { "(energy<=%d && loc=%s && sys_actions=%s) -> X(energy=0)" % (alldropenergy2[i - 1], locStr, actStr) } sys_safe |= { "(sys_actions!=%s && !%s) -> (X(!%s))" % (actStr, actboolStr, actboolStr) } # don't allow other actions to arbitrarily set this to True sys_safe |= {"%s -> X(%s)" % (actboolStr, actboolStr)} # if picture is taken, 'stays' taken sys_prog |= {"picAtS2Taken"} # goal --> trying to take picture at s2 # 0 1 2 3 4 # atakesample# alldropenergy3 = [1, 1, 1, 1, 1] alldroprisk3 = [0, 0, 0, 0, 0] for i in range(1, 5 + 1): # [1] atakepicture1,picAtS1Taken, ... actStr = "atakesample%d" % i energystr = dropStr("energy", energylo, energyhi, alldropenergy3[i - 1]) sys_safe |= { "sys_actions=%s -> (%s && (X(energy=0) <-> energy<=%d))" % (actStr, energystr, alldropenergy3[i - 1]) } # wait action keeps energy at same level (no energy used) riskstr = dropStr("risk", risklo, riskhi, alldroprisk3[i - 1]) sys_safe |= { "sys_actions=%s -> (%s && (X(risk=0) <-> risk<=%d))" % (actStr, riskstr, alldroprisk3[i - 1]) } # wait action keeps energy at same level (no energy used) actboolStr = "samAtS%dTaken" % i locStr = "s%d" % i sys_sws.actions.add(actStr) sys_sws.transitions.add("s%d" % i, "s%d" % i, actions=actStr) sys_vars.update({actboolStr: "boolean"}) sys_init |= {"!%s" % actboolStr} sys_safe |= { "(energy>%d && loc=%s && sys_actions=%s) -> X(%s)" % (alldropenergy3[i - 1], locStr, actStr, actboolStr) } sys_safe |= { "(energy<=%d && loc=%s && sys_actions=%s) -> X(energy=0)" % (alldropenergy3[i - 1], locStr, actStr) } sys_safe |= { "(sys_actions!=%s && !%s) -> (X(!%s))" % (actStr, actboolStr, actboolStr) } # don't allow other actions to arbitrarily set this to True sys_safe |= {"%s -> X(%s)" % (actboolStr, actboolStr)} # if sample is taken, 'stays' taken # sys_prog |= {'samAtS5Taken'} # goal --> trying to take sample at s5 # # after all sys_goal specs are written... # goal_conditions = "" for goalpieceStr in list(sys_prog): goal_conditions += goalpieceStr + " && " goal_conditions = goal_conditions[0 : len(goal_conditions) - 4] # remove trailing ' && ' # set up stepcounter at the end of everything, after all sys_goal specs are written: steplo = 0 stephi = 8 # lower this number to try and force gr1c to be more efficient sys_vars.update({"stepCounter": (steplo, stephi)}) sys_init |= {"stepCounter=%d" % steplo} stepstr = riseStr("stepCounter", steplo, stephi, 1) sys_safe |= { "!(%s) -> %s" % (goal_conditions, stepstr) } # goal_conditions not met implies stepCounter increases by 1 each time stepstr = riseStr("stepCounter", steplo, stephi, 0) sys_safe |= { "(%s) -> %s" % (goal_conditions, stepstr) } # goal_conditions met implies stepCounter doesn't increase (any more) # then lower stephi to try and force gr1c to find a more efficient (shortest number of actions) solution sys_safe |= { "stepCounter < %d" % (stephi) } # must keep counter below stephi; requires below that we stop counting steps after we finish all goals # add this in so we can tell when we're just doing extra stuff post-whatever sys_vars.update({"sysgoalsReached": "boolean"}) sys_init |= {"!sysgoalsReached"} sys_safe |= { "!(%s) <-> !sysgoalsReached" % (goal_conditions) } # goal_conditions not met implies sysgoals(not_yet)Reached sys_safe |= {"(%s) <-> sysgoalsReached" % (goal_conditions)} # goal_conditions met implies sysgoalsReached # changes might've been made this far down, so show again... print(sys_sws) # show the Finite Transition System, make sure it was encoded properly sys_sws.save("deliberative_%sb.pdf" % ver) # save the visual diagram of the FTS, for same reason print("Done saving deliberative_%sb.pdf" % ver) print("Creating spec for sys_sws system") # Create the specification specs = spec.GRSpec( env_vars=env_vars, sys_vars=sys_vars, env_init=env_init, sys_init=sys_init, env_safety=env_safe, sys_safety=sys_safe, env_prog=env_prog, sys_prog=sys_prog, ) print(specs.pretty()) # GRSpec(env_vars=None, sys_vars=None, env_init='', sys_init='', env_safety='', sys_safety='', env_prog='', sys_prog='') # (env_init & []env_safety & []<>env_prog_1 & []<>env_prog_2 & ...) # -> (sys_init & []sys_safety & []<>sys_prog_1 & []<>sys_prog_2 & ...) # # C{env_vars}: alias for C{input_variables} of L{LTL}, concerning variables that are determined by the environment # C{env_init}: a list of string that specifies the assumption about the initial state of the environment. # C{env_safety}: a list of string that specifies the assumption about the evolution of the environment state. # C{env_prog}: a list of string that specifies the justice assumption on the environment. # C{sys_vars}: alias for C{output_variables} of L{LTL}, concerning variables that are controlled by the system. # C{sys_init}: a list of string that specifies the requirement on the initial state of the system. # C{sys_safety}: a list of string that specifies the safety requirement. # C{sys_prog}: a list of string that specifies the progress requirement. print("Done creating spec for sys_sws system") # Controller synthesis # # At this point we can synthesize the controller using one of the available # methods. Here we make use of gr1c. # print("Synthesizing solution for sys_sws system") ctrl = synth.synthesize("gr1c", specs, sys=sys_sws) print("Done synthesizing solution for sys_sws system") print("Creating .png file for sys_sws system") if ctrl is None: print("Got gr1c error, not attempting save =or= print-to-screen =or= MealyMachine dumpsmach") else: # Generate a graphical representation of the controller for viewing if not ctrl.save("deliberative_%s_sws.png" % ver): print("Couldn't save .png file, printing ctrl instead") print(ctrl) print("Done printing ctrl instead") print("Done creating .png file for sys_sws system") print("Writing MealyMachine out via dumpsmach") # ctrl is a MealyMachine from tulip import dumpsmach dumpsmach.write_python_case( filename="dumpsmachtest_dlap%s.py" % ver, M=ctrl, classname="TulipStrategy", start="Sinit" ) print("Done writing MealyMachine out to dumpsmachtest_dlap%s.py" % ver)
sys_safe |= {'((driving_to_leave && !clear) -> X(driving_to_leave))'} sys_safe |= {'((driving_to_leave && clear) -> X(at_pick_up))'} sys_safe |= {'((at_pick_up && !clear) -> X(at_pick_up))'} sys_safe |= {'((at_pick_up && clear) -> X(leave))'} # Create the specification specs = spec.GRSpec(env_vars, sys_vars, env_init, sys_init, env_safe, sys_safe, env_prog, sys_prog) specs.moore = True # synthesizer should find initial system values that satisfy # `env_init /\ sys_init` and work, for every environment variable # initial values that satisfy `env_init`. specs.qinit = '\E \A' ctrl = synth.synthesize(specs, sys=sys) assert ctrl is not None, 'unrealizable' # @synthesize_end@ # # Generate a graphical representation of the controller for viewing, # or a textual representation if pydot is missing. # # @plot_print@ #if not ctrl.save('simplestspec_ctrl.png'): # print(ctrl) # @plot_print_end@ # appended as in documentation chapter 6 dumpsmach.write_python_case("simplestspec_ctrl.py", ctrl, classname="ExampleCtrl")
def solve_problem(init_state, file_name, row_number, col_number, list_target, sys_name, sup_target_list, list_obstacles): print row_number print col_number print sys_name print sup_target_list print list_target #Environment variable env_vars = {} env_vars['target_' + sys_name] = (0, len(sup_target_list)) #Envrionment init value #env_init = {'target_{sys_name} = {last_value}'.format(sys_name=sys_name, last_value=len(sup_target_list))} env_init = { 'target_{sys_name} = {last_value}'.format( sys_name=sys_name, last_value=len(sup_target_list)) } #env_init = {'!(target_{sys_name} = {last_value})'.format(sys_name=sys_name, last_value=0)} #env_init = {'!(target_{sys_name} = {last_value})'.format(sys_name=sys_name, last_value=1)} #Environment prog env_prog = {} #env_prog ={'target_{sys_name} = {last_value}'.format(sys_name=sys_name, last_value=0)} #env_prog ={'target_{sys_name} = {last_value}'.format(sys_name=sys_name, last_value=1)} #env_prog ={"(target_{sys_name} = {last_value})".format(sys_name=sys_name , last_value=0)} env_prog = { "! (target_{sys_name} = {last_value})".format( sys_name=sys_name, last_value=len(sup_target_list)) } env_safe = set() env_safe |= { '(target_{sys_name} ={last_value}) -> X (!(target_{sys_name} = {last_value}))' .format(sys_name=sys_name, last_value=len(sup_target_list)) } for elem in range(len(sup_target_list)): env_safe |= { '(target_{sys_name} ={elem}) -> X ((target_{sys_name} = {elem}) || (target_{sys_name} = {last_value}))' .format(sys_name=sys_name, elem=elem, last_value=len(sup_target_list)) } #system variable sys_vars = {} sys_vars[sys_name] = (0, (row_number * col_number) - 1) #sys_vars['follow_target'] = (0,1) sys_vars['follow_complete'] = (0, 1) sys_vars['stage_' + sys_name] = (0, len(list_target)) #system init variable sys_init = set() sys_init |= { "(stage_{sys_name} = {init_value})".format(sys_name=sys_name, init_value=0) } #sys_init |= {'follow_target = 0'} sys_init |= {'follow_complete = 1'} sys_init |= {sys_name + ' = ' + str(init_state)} #System prog sys_prog = set() sys_prog |= { "(stage_{sys_name} = {last_value})".format(sys_name=sys_name, last_value=len(list_target)) } #System safety sys_safe = set() for elem in range(len(list_target)): sys_safe |= { '(stage_{sys_name} = {value}) -> X ((stage_{sys_name} = {value}) || (stage_{sys_name} = {value_1}))' .format(sys_name=sys_name, value=elem, value_1=elem + 1) } sys_safe |= { '(stage_{sys_name} = {last_value}) -> X ( (stage_{sys_name} = 0) )'. format(sys_name=sys_name, last_value=len(list_target)) } sys_safe |= { ' (target_{sys_name} = {last_value}) -> X (follow_complete = 0)'. format(sys_name=sys_name, last_value=len(sup_target_list)) } #sys_safe |= {' ! (target_{sys_name} = {last_value}) && X (follow_complete = 1) -> X (follow_complete = 0)'.format(sys_name=sys_name,last_value=len(sup_target_list))} #sys_safe |= {'! (target_{sys_name} = {last_value}) -> (follow_target = 1)'.format(sys_name=sys_name,last_value=len(sup_target_list))} #sys_safe |= {'(!(target_{sys_name} = {last_value})) -> (follow_target = 1)'.format(sys_name=sys_name,last_value=len(sup_target_list))} #To modify sys_safe |= allow_moves(row_number, col_number, sys_name, list_obstacles) sys_safe |= handle_static_obstacles(list_obstacles, sys_name) sys_safe |= handle_target_point(row_number, col_number, list_target, sys_name, sup_target_list) specs = spec.GRSpec(env_vars, sys_vars, env_init, sys_init, env_safe, sys_safe, env_prog, sys_prog) print specs.pretty() specs.moore = True specs.qinit = '\E \A' ctrl = synth.synthesize('gr1c', specs) assert ctrl is not None, 'Unrealizable' #print ctrl dumpsmach.write_python_case(file_name + '_controller.py', ctrl, classname=file_name + 'Controller')
def create_w_specs_all_init_cond(current_horizon, x_goal_loc, y_goal_loc, w_part, transition_part, dimension_x, dimension_y): # Don't synthesize for corner w regions (i.e. w region that's only a corner) that can't be fulfilled (... so ugly) # Note: Better way of doing this would be to not add corner regions to w_part... if (w_part[current_horizon] == [(dimension_x, dimension_y, 1)] or w_part[current_horizon] == [(dimension_x, dimension_y, 2)] or w_part[current_horizon] == [(dimension_x, dimension_y, 3)] or w_part[current_horizon] == [(dimension_x, dimension_y, 4)] or w_part[current_horizon] == [(dimension_x, 1, 1)] or w_part[current_horizon] == [(dimension_x, 1, 2)] or w_part[current_horizon] == [(dimension_x, 1, 3)] or w_part[current_horizon] == [(dimension_x, 1, 4)] or w_part[current_horizon] == [(1, dimension_y, 1)] or w_part[current_horizon] == [(1, dimension_y, 2)] or w_part[current_horizon] == [(1, dimension_y, 3)] or w_part[current_horizon] == [(1, dimension_y, 4)] or w_part[current_horizon] == [(1, 1, 1)] or w_part[current_horizon] == [(1, 1, 2)] or w_part[current_horizon] == [(1, 1, 3)] or w_part[current_horizon] == [(1, 1, 4)]): return # Create FTS and actions sys_auto = transys.FTS() sys_auto.sys_actions.add_from({'Stop', 'go', 'goVert', 'goHori'}) # Fake AP's to enable all specs related to base and goal position sys_auto.states.add_from(['fAKE']) sys_auto.atomic_propositions.add_from({'Base', 'goalPos'}) sys_auto.states['fAKE']['ap'] |= {'Base', 'goalPos'} # Add all AP's for the transition space, including those tied to 'Base' and 'goalPos' if present in transition space for locat in transition_part[current_horizon]: add_ap_sub = 'Pos' + str(locat[0]) + '_' + str(locat[1]) + 'Ori' + str(locat[2]) sys_auto.states.add_from([add_ap_sub]) if locat[0] == 2 and locat[1] == 2: # TODO add some global indicator of the base location sys_auto.states[add_ap_sub]['ap'] |= {'Base'} if locat[0] == x_goal_loc and locat[1] == y_goal_loc: sys_auto.states[add_ap_sub]['ap'] |= {'goalPos'} # Initial condition, empty set sys_auto_init = set() #print(transition_part[current_horizon]) #print(w_part[current_horizon]) #input('uhmmm...') # NOTE: that current_horizon is 1, 2, 3, ... # Create all transitions through brute force method of checking existence of locations in the transition region next # to every starting point, dependent on the orientation. This is ran on transition region and inclusion in w region # is checked in creating transitions. This is because all w regions are contained in the transition region, and # transitions from a w region are different than those form just transition regions for locat in transition_part[current_horizon]: init = 'Pos' + str(locat[0]) + '_' + str(locat[1]) + 'Ori' + str(locat[2]) if locat in w_part[current_horizon]: sys_auto.transitions.add_comb({init}, {init}, sys_actions="Stop") # Transitions allowed if orientation is up if locat[2] == 1: if (locat[0], locat[1] + 1, 1) in transition_part[current_horizon]: endloc = 'Pos' + str(locat[0]) + '_' + str(locat[1] + 1) + 'Ori' + str(1) sys_auto.transitions.add_comb({init}, {endloc}, sys_actions="goVert") if (locat[0] + 1, locat[1] + 1, 2) in transition_part[current_horizon]: endloc = 'Pos' + str(locat[0] + 1) + '_' + str(locat[1] + 1) + 'Ori' + str(2) sys_auto.transitions.add_comb({init}, {endloc}, sys_actions="go") if (locat[0] - 1, locat[1] + 1, 4) in transition_part[current_horizon]: endloc = 'Pos' + str(locat[0] - 1) + '_' + str(locat[1] + 1) + 'Ori' + str(4) sys_auto.transitions.add_comb({init}, {endloc}, sys_actions="go") # Transitions allowed if orientation is right elif locat[2] == 2: if (locat[0] + 1, locat[1], 2) in transition_part[current_horizon]: endloc = 'Pos' + str(locat[0] + 1) + '_' + str(locat[1]) + 'Ori' + str(2) sys_auto.transitions.add_comb({init}, {endloc}, sys_actions="goHori") if (locat[0] + 1, locat[1] + 1, 1) in transition_part[current_horizon]: endloc = 'Pos' + str(locat[0] + 1) + '_' + str(locat[1] + 1) + 'Ori' + str(1) sys_auto.transitions.add_comb({init}, {endloc}, sys_actions="go") if (locat[0] + 1, locat[1] - 1, 3) in transition_part[current_horizon]: endloc = 'Pos' + str(locat[0] + 1) + '_' + str(locat[1] - 1) + 'Ori' + str(3) sys_auto.transitions.add_comb({init}, {endloc}, sys_actions="go") # Transitions allowed if orientation is down elif locat[2] == 3: if (locat[0], locat[1] - 1, 3) in transition_part[current_horizon]: endloc = 'Pos' + str(locat[0]) + '_' + str(locat[1] - 1) + 'Ori' + str(3) sys_auto.transitions.add_comb({init}, {endloc}, sys_actions="goVert") if (locat[0] + 1, locat[1] - 1, 2) in transition_part[current_horizon]: endloc = 'Pos' + str(locat[0] + 1) + '_' + str(locat[1] - 1) + 'Ori' + str(2) sys_auto.transitions.add_comb({init}, {endloc}, sys_actions="go") if (locat[0] - 1, locat[1] - 1, 4) in transition_part[current_horizon]: endloc = 'Pos' + str(locat[0] - 1) + '_' + str(locat[1] - 1) + 'Ori' + str(4) sys_auto.transitions.add_comb({init}, {endloc}, sys_actions="go") # Transitions allowed if orientation is left elif locat[2] == 4: if (locat[0] - 1, locat[1], 4) in transition_part[current_horizon]: endloc = 'Pos' + str(locat[0] - 1) + '_' + str(locat[1]) + 'Ori' + str(4) sys_auto.transitions.add_comb({init}, {endloc}, sys_actions="goHori") if (locat[0] - 1, locat[1] + 1, 1) in transition_part[current_horizon]: endloc = 'Pos' + str(locat[0] - 1) + '_' + str(locat[1] + 1) + 'Ori' + str(1) sys_auto.transitions.add_comb({init}, {endloc}, sys_actions="go") if (locat[0] - 1, locat[1] - 1, 3) in transition_part[current_horizon]: endloc = 'Pos' + str(locat[0] - 1) + '_' + str(locat[1] - 1) + 'Ori' + str(3) sys_auto.transitions.add_comb({init}, {endloc}, sys_actions="go") # Create possible transitions for initial conditions in only the transition region. Only transitions are # staying still, assigned to both action groups. This works because in implementation the controllers will # switch to the next horizon here else: sys_auto.transitions.add_comb({init}, {init}, sys_actions="Stop") sys_auto.transitions.add_comb({init}, {init}, sys_actions="go") check_hori = None if w_part[current_horizon - 1] is None: check_hori = None else: check_hori = None for ct in w_part[current_horizon - 1]: if ct is not None: if 'Pos' + str(ct[0]) + '_' + str(ct[1]) + 'Ori' + str(ct[2]) not in phi_states: check_hori = True # Begin generating the specifications!! # Create the additional environmental variables, including signal for w region next to goal env_auto_vars = {'fire'}#'StopSignal', if current_horizon == 1 or check_hori is None: env_auto_vars |= {'SyncHori'}#, 'SyncSignal', 'SyncVert'} #env_auto_vars |= {'SH1', 'SH2', 'SHb'}#, 'SV1', 'SV2', 'SVb', 'S1', 'S2', 'Sb'} # Create the environment specifications, including progress related to sync signal next to goal env_auto_safe = set() env_auto_init = {'!fire'}#'!StopSignal', env_auto_prog = {'!fire'}#'!StopSignal', #if current_horizon == 1 or check_hori is None: #env_auto_prog |= {'SyncSignal||SyncVert||SyncHori'} #if current_horizon == 1 or check_hori is None: #env_auto_safe |= {'SyncSignal->(!SyncVert && !SyncHori)'} #env_auto_safe |= {'SyncVert->(!SyncSignal && !SyncHori)'} #env_auto_safe |= {'SyncHori->(!SyncSignal && !SyncVert)'} # Create the specification for [](SyncHori->(SyncHori U Goal)) #env_auto_safe |= {'(SH1&&!SH2&&!SHb)||(!SH1&&SH2&&!SHb)||(!SH1&&!SH2&&SHb)'} #env_auto_init |= {'SH1'} #env_auto_prog |= {'SH1||SH2'} #env_auto_safe |= {'((SH1 && (!SyncHori || goalPos) && X SH1) || ' + # '(SH1 && (SyncHori && !goalPos) && X SH2) || ' + # '(SH2 && (SyncHori && !goalPos) && X SH2) || ' + # '(SH2 && !SyncHori && X SHb) || ' + # '(SH2 && (SyncHori && goalPos) && X SH1) || ' + # '(SHb && X SHb))'} #env_auto_safe |= {'SyncSignal->(!((!goalPos)U(!SyncSignal)))'} #env_auto_safe |= {'SyncVert->(!((!goalPos)U(!SyncVert)))'} #env_auto_safe |= {'SyncHori->(!((!goalPos)U(!SyncHori)))'} #env_auto_safe |= {'X VertPrev <-> SyncVert'} #env_auto_safe |= {'X HoriPrev <-> SyncHori'} #env_auto_safe |= {'(X (Sync_Hori_extra) && goalPos)->(SyncHori)'} #env_auto_safe |= {'(X(X (Sync_Hori_extra) && goalPos))->(SyncHori)'} #env_auto_safe |= {'(X (Sync_Vert_extra) && goalPos)->(SyncVert)'} # System variables and safety specification empty sets sys_auto_vars = set() sys_auto_safe = set() # Add relevant phi variables to safety (i.e. all phi contained within this region). Never enter phi locations phi = '' for locat in transition_part[current_horizon]: state = 'Pos' + str(locat[0]) + '_' + str(locat[1]) + 'Ori' + str(locat[2]) for names in phi_states: if state == names: phi = phi + '!(loc = "' + names + '")&&' phi = phi + 'True' sys_auto_safe |= {phi} # Empty initial progress sys_auto_prog = set() # Display progress statement to user print(('Beginning synthesis of W' + str(current_horizon) + ' for goal (' + str(x_goal_loc) + ',' + str(y_goal_loc) + ')!')) # Cycle through all initial conditions in this w region for synthesizing controller for idxn, locat in enumerate(w_part[current_horizon]): locat_sub = locat #if locat == (9, 8, 3): # print('here') # input('wait...') # Create checks to see if current position is viable initial condition current_state = 'Pos' + str(locat_sub[0]) + '_' + str(locat_sub[1]) + 'Ori' + str(locat_sub[2]) # Run through names in phi_states to check if it's included indicator = 0 for names in phi_states: if current_state == names: indicator = 1 # If current state passed, then add to initial condition and synthesize. Otherwise, move to next I.C. if indicator == 0: sys_auto_init = {'(loc = "' + current_state + '")'} else: continue # Create the progress statements and synthesize. Progress statements differ depending on current horizon # For horizon W1 if current_horizon == 1 or check_hori is None: # This section is the 'sync' version of specs, which is just the normal "correct" version print('Sync synthesis for ' + current_state) # Start timer for synthesis start_time = time.time() statement_hori = ((x_goal_loc + 1, y_goal_loc) not in obstacle_location and \ (x_goal_loc - 1, y_goal_loc) not in obstacle_location and 'Pos' + str(x_goal_loc + 1) + '_' + \ str(y_goal_loc) + 'Ori2' \ not in phi_states and 'Pos' + str(x_goal_loc + 1) + '_' + str(y_goal_loc) + 'Ori4' not in phi_states and \ 'Pos' + str(x_goal_loc - 1) + '_' + str(y_goal_loc) + 'Ori2' not in phi_states and 'Pos' + \ str(x_goal_loc - 1) + '_' + str(y_goal_loc) + \ 'Ori4' not in phi_states) statement_vert = ((x_goal_loc, y_goal_loc + 1) not in obstacle_location and \ (x_goal_loc, y_goal_loc - 1) not in obstacle_location and 'Pos' + str(x_goal_loc) + '_' + str(y_goal_loc + 1) + 'Ori1' \ not in phi_states and 'Pos' + str(x_goal_loc) + '_' + str(y_goal_loc + 1) + 'Ori3' not in phi_states and \ 'Pos' + str(x_goal_loc) + '_' + str(y_goal_loc - 1) +'Ori1' not in phi_states and 'Pos' + \ str(x_goal_loc) + '_' + str(y_goal_loc - 1) + 'Ori3' not in phi_states) sync_hori_cond = '(!Sync_Hori_extra && goalPos)' sync_vert_cond = '(!Sync_Vert_extra && goalPos)' sync_cond = '(X (Sync_extra) && goalPos)' sync_spec_hori = 'Sync_Hori_extra' sync_spec_vert = 'Sync_Vert_extra' sync_spec = 'Sync_extra' stop_condition_all = 'StopSignal&&!fire' if statement_hori and statement_vert: sys_auto_vars |= {'Sync_Hori_extra'}#, 'Sync_Vert_extra', 'Sync_extra'}#, 'SH_proxy', 'SV_proxy', 'S_proxy'}#, 'Sync_vert_prev', 'Sync_hori_prev'} sys_auto_init |= {'Sync_Hori_extra'}#, 'Sync_Vert_extra', 'Sync_extra'}#, '!SH_proxy', '!SV_proxy', '!S_proxy'} # Proxy variables and rules #sys_auto_safe |= {'(!SH_proxy&&!SV_proxy&&!S_proxy)||(SH_proxy&&!SV_proxy&&!S_proxy)||' + # '(!SH_proxy&&SV_proxy&&!S_proxy)||(!SH_proxy&&!SV_proxy&&S_proxy)'} #sys_auto_safe |= {'((SH_proxy&&!SV_proxy&&!S_proxy)||' + # '(!SH_proxy&&SV_proxy&&!S_proxy)||(!SH_proxy&&!SV_proxy&&S_proxy))->' + # '((SH_proxy <-> X SH_proxy)&&(SV_proxy <-> X SV_proxy)&&(S_proxy <-> X S_proxy))'} #sys_auto_safe |= {'(!SH_proxy&&!SV_proxy&&!S_proxy&&SyncHori)->(X SH_proxy)'} #sys_auto_safe |= {'(!SH_proxy&&!SV_proxy&&!S_proxy&&SyncVert)->(X SV_proxy)'} #sys_auto_safe |= {'(!SH_proxy&&!SV_proxy&&!S_proxy&&SyncSignal)->(X S_proxy)'} #sys_auto_safe |= {'(goalPos&&!Sync_Hori_extra)->(X !SH_proxy)'} #sys_auto_safe |= {'(goalPos&&!Sync_Vert_extra)->(X !SV_proxy)'} #sys_auto_safe |= {'(goalPos&&!Sync_extra)->(X !S_proxy)'} #sys_auto_safe |= {'(X Sync_vert_prev <-> SyncVert) && (X Sync_hori_prev <-> SyncHori)'} sys_auto_safe |= {'((!SyncHori)&& X Sync_Hori_extra) || ((X (Sync_Hori_extra) <-> goalPos)) || (Sync_Hori_extra && !SyncHori)'}#{'(X (Sync_Hori_extra) <-> goalPos) || (Sync_Hori_extra && !SyncHori)'} #sys_auto_safe |= {'((!SyncVert)&& X Sync_Vert_extra) || ((X (Sync_Vert_extra) <-> goalPos)) || (Sync_Vert_extra && !SyncVert)'} #sys_auto_safe |= {'(X (Sync_extra) <-> goalPos) || (Sync_extra && !S_proxy)'}#{'(X (Sync_extra) <-> goalPos) || (Sync_extra && !SyncSignal)'} #stop_condition1 = '(!(X(' + sync_hori_cond + '))&&!(' + sync_hori_cond + '))' #stop_condition2 = '(!(X(' + sync_vert_cond + '))&&!(' + sync_vert_cond + '))' #stop_condition3 = '(!(X(' + sync_cond + '))&&!(' + sync_cond + '))' #sys_auto_safe |= {'(' + stop_condition_all + '&&' + stop_condition1 + '&&' \ # + stop_condition2 + '&&' + stop_condition3 + ')->(X(sys_actions = "Stop"))'} #sys_auto_safe |= {'(!(' + stop_condition_all + '&&' + stop_condition1 + '&&' \ # + stop_condition2 + '&&' + stop_condition3 + '))->(X(sys_actions != "Stop"))'} sys_auto_safe |= {'X(sys_actions != "Stop")'} #sys_auto_safe |= {'(' + sync_hori_cond + ')->((X sys_actions = "goHori") && (sys_actions = "goHori"))'} #sys_auto_safe |= {'(' + sync_vert_cond + ')->((X(sys_actions = "goVert")) && (sys_actions = "goVert"))'} sys_auto_prog |= {sync_spec_hori} #sys_auto_prog |= {sync_spec_vert} #sys_auto_prog |= {sync_spec} '''elif statement_vert: stop_condition = '(StopSignal&&!fire&&!(X(' + sync_spec_vert + '))&&'+ \ '!(X(' + sync_spec + ')))' sys_auto_safe |= {stop_condition + '->(X(sys_actions = "Stop"))'} sys_auto_safe |= {'(!' + stop_condition + ')->(X(sys_actions != "Stop"))'} sys_auto_safe |= {'(X(' + sync_spec_vert + '))->(sys_actions = "goVert" && X(sys_actions = "goVert"))'} sys_auto_prog = {sync_spec_vert} sys_auto_prog |= {sync_spec} elif statement_hori: stop_condition = '(StopSignal&&!fire&&!(X(' + sync_spec_hori + '))&&'+ \ '!(X(' + sync_spec + ')))' sys_auto_safe |= {stop_condition + '->(X(sys_actions = "Stop"))'} sys_auto_safe |= {'(!' + stop_condition + ')->(X(sys_actions != "Stop"))'} sys_auto_safe |= {'(X(' + sync_spec_hori + '))->(sys_actions = "goHori" && X(sys_actions = "goHori"))'} sys_auto_prog = {sync_spec_hori} sys_auto_prog |= {sync_spec} else: stop_condition = '(StopSignal&&!fire)' sys_auto_safe |= {stop_condition + '->(X(sys_actions = "Stop"))'} sys_auto_safe |= {'(!' + stop_condition + ')->(X(sys_actions != "Stop"))'} sys_auto_prog = {sync_spec}''' #if statement_vert: # Spec just states that the sync signal implies goal position is there # Create the GR spec for all the generated env and sys specs specs_final_sync = spec.GRSpec(env_auto_vars, sys_auto_vars, env_auto_init, sys_auto_init, env_auto_safe, sys_auto_safe, env_auto_prog, sys_auto_prog) print(specs_final_sync) # Synthesizer attributes specs_final_sync.moore = True option = 'omega' specs_final_sync.qinit = '\E \A' # synthesizer should find initial system values that satisfy # `env_init /\ sys_init` and work, for every environment variable # initial values that satisfy `env_init`. # SYNTHESIZE!!! ctrl_final_sync = synth.synthesize(option, specs_final_sync, env=None, sys=sys_auto, ignore_sys_init=True) print(sys.getsizeof(ctrl_final_sync)) # failure results in adjustments to the horizon related to current I.C. if ctrl_final_sync is None: print('Failed to synthesize ' + current_state + ', moving to next w_part and transition_part') w_part[current_horizon + 1].append(locat) if locat not in transition_part[current_horizon + 1]: transition_part[current_horizon + 1].append(locat) w_part[current_horizon][idxn] = None transition_part[current_horizon].remove(locat) #if locat == (9, 8, 2): # print('here') # print(w_part[current_horizon]) # input('wait...') # Stopwatch and print synth_time = time.time() - start_time print(synth_time) # Write controller to relevant location if it synthesized filename = 'ctrls3/Goal' + str(x_goal_loc) + '_' + str(y_goal_loc) + '/G' + str(x_goal_loc) + '_' + \ str(y_goal_loc) + current_state + '.py' #'_W' + str(current_horizon) + if ctrl_final_sync is not None: dumpsmach.write_python_case(filename, ctrl_final_sync) #if locat == (9, 8, 2): # print('here') # print(w_part[current_horizon]) # input('wait...') # All other horizons from the first one (>= W2) else: print('Synthesis for ' + current_state) # Start timer for synthesis start_time = time.time() # Generate progress to any area of transition region that aren't in the w region (inner layer) spec_inter = '((' for locat2 in transition_part[current_horizon]: if locat2 not in w_part[current_horizon]: locations = 'Pos' + str(locat2[0]) + '_' + str(locat2[1]) + 'Ori' + str(locat2[2]) spec_inter = spec_inter + 'loc = "' + locations + '")||(' # Finish tail end of progress spec (false is there to wrap up string generated by loop) spec_inter = spec_inter + 'False))' sys_auto_prog |= {spec_inter} stop_condition = '(StopSignal&&!fire)' sys_auto_safe |= {stop_condition + '->(X(sys_actions = "Stop"))'} sys_auto_safe |= {'(!' + stop_condition + ')->(X(sys_actions != "Stop"))'} # Create the GR spec for all the generated env and sys specs specs_inter = spec.GRSpec(env_auto_vars, sys_auto_vars, env_auto_init, sys_auto_init, env_auto_safe, sys_auto_safe, env_auto_prog, sys_auto_prog) # Synthesizer attributes specs_inter.moore = True option = 'omega' specs_inter.qinit = '\E \A' # synthesizer should find initial system values that satisfy # `env_init /\ sys_init` and work, for every environment variable # initial values that satisfy `env_init`. # SYNTHESIZE!!! ctrl_inter = synth.synthesize(option, specs_inter, sys=sys_auto, ignore_sys_init=True) # Failure results in adjustments to the horizon related to current I.C. if ctrl_inter is None: print('Failed to synthesize ' + current_state + ', moving to next w_part and transition_part') w_part[current_horizon + 1].append(locat) if locat not in transition_part[current_horizon + 1]: transition_part[current_horizon + 1].append(locat) w_part[current_horizon][idxn] = None transition_part[current_horizon].remove(locat) # Stopwatch and print synth_time = time.time() - start_time print(synth_time) # Write controller to relevant location if it synthesized filename = 'ctrls/Goal' + str(x_goal_loc) + '_' + str(y_goal_loc) + '/G' + str(x_goal_loc) + '_' + \ str(y_goal_loc) + current_state + '.py' #'_W' + str(current_horizon) + if ctrl_inter is not None: dumpsmach.write_python_case(filename, ctrl_inter)
# sys_safe |= {'((env1 = '+str(iter1)+') && (loc = '+str(iter1+ (env_row-1)*dim +1)+')) -> X !(loc = '+str(iter1 + env_row*dim +1)+')'} # sys_safe |= {'((env1 = '+str(iter1+1)+') && (loc = '+str(iter1+ (env_row-1)*dim)+')) -> X !(loc = '+str(iter1 + env_row*dim)+')'} # if env_row <dim-1 : # sys_safe |= {'((env1 = '+str(iter1)+') && (loc = '+str(iter1+ (env_row+1)*dim +1)+')) -> X !(loc = '+str(iter1 + env_row*dim +1)+')'} # sys_safe |= {'((env1 = '+str(iter1+1)+') && (loc = '+str(iter1+ (env_row+1)*dim)+')) -> X !(loc = '+str(iter1 + env_row*dim)+')'} specs = spec.GRSpec(env_vars, sys_vars, env_init, sys_init, env_safe, sys_safe, env_prog, sys_prog) #GR(1) specification created # # Controller synthesis # # The controller decides based on current variable values only, # without knowing yet the next values that environment variables take. # A controller with this information flow is known as Moore. specs.moore = True # Ask the synthesizer to find initial values for system variables # that, for each initial values that environment variables can # take and satisfy `env_init`, the initial state satisfies # `env_init /\ sys_init`. specs.qinit = '\E \A' # i.e., "there exist sys_vars: forall sys_vars" ctrl = synth.synthesize('gr1c', specs) assert ctrl is not None, 'unrealizable' #if not ctrl.save('gr1.png'): # print(ctrl) print ctrl #print specs.pretty() dumpsmach.write_python_case("rowEnvController.py", ctrl, classname="RowEnvCtrl")
# sys_safe |= {'(env1 = '+str(iter1)+') && (loc = '+str(pos)+') -> X ('+get_spec_list_neighbor('loc',state_when_close_next)+')'} #Don't allow sys and env to exchange position specs = spec.GRSpec(env_vars, sys_vars, env_init, sys_init, env_safe, sys_safe, env_prog, sys_prog) #GR(1) specification created #print specs.pretty() # # Controller synthesis # # The controller decides based on current variable values only, # without knowing yet the next values that environment variables take. # A controller with this information flow is known as Moore. specs.moore = True # Ask the synthesizer to find initial values for system variables # that, for each initial values that environment variables can # take and satisfy `env_init`, the initial state satisfies # `env_init /\ sys_init`. specs.qinit = '\E \A' # i.e., "there exist sys_vars: forall sys_vars" #assert not specs.sys_safe ctrl = synth.synthesize('gr1c', specs) assert ctrl is not None, 'unrealizable' #if not ctrl.save('gr1.png'): # print(ctrl) #print ctrl #print specs.pretty() dumpsmach.write_python_case("ObstacleController.py", ctrl, classname="ObstacleCtrl")
sys_prog = {'goal'} # []<>goal sys_safe = {'((signal && red)->X(signal)) && (goal -> X(goal))'} #sys_prog |= {'X0reach'} # Create the specification specs = spec.GRSpec(env_vars, sys_vars, env_init, sys_init, env_safe, sys_safe, env_prog, sys_prog) specs.moore = True # synthesizer should find initial system values that satisfy # `env_init /\ sys_init` and work, for every environment variable # initial values that satisfy `env_init`. specs.qinit = '\E \A' ctrl = synth.synthesize(specs, sys=sys) assert ctrl is not None, 'unrealizable' # @synthesize_end@ # # Generate a graphical representation of the controller for viewing, # or a textual representation if pydot is missing. # # @plot_print@ if not ctrl.save('singlelane_signal.png'): print(ctrl) # @plot_print_end@ # appended as in documentation chapter 6 dumpsmach.write_python_case("singlelane_signal_fsm.py", ctrl, classname="ExampleFSM")
# the upper left corner of the grid while at the same time responding # to the moveToTheEgg signal by visiting the eggLocation. The LTL # specification is given by # # []<> X0 && [](moveToTheEgg -> <>eggLocation) && [](!moveToTheEgg -> <>X0) # # Since this specification is not in GR(1) form, we introduce one # environment variable XeggReach that is initialized to True and the specification : # [](moveToTheEgg -> <>eggLocation) # becomes : # [](X (XeggReach) <-> (eggLocation)) || (XeggReach && !moveToTheEgg), # # Augment the system description to make it GR(1) sys_init = {'XeggReach', 'batteryLevel = 1', 'segwayLocation = 0'} #does not work with 2x sys_init ={...} sys_safe |= { '(X (XeggReach) <-> (segwayLocation=eggLocation)) || (XeggReach && !moveToTheEgg)', } sys_prog |= {'XeggReach', 'segwayLocation = 0'} # Create a GR(1) specification specs = spec.GRSpec(env_vars, sys_vars, env_init, sys_init, env_safe, sys_safe, env_prog, sys_prog) specs.moore = True specs.qinit = '\E \A' # Controller synthesis strategy = synth.synthesize('omega', specs) assert strategy is not None, 'unrealizable' dumpsmach.write_python_case("segwayController.py", strategy, classname="controller") machines.random_run(strategy, N=100)
#Don't allow sys and env to exchange position specs = spec.GRSpec(env_vars, sys_vars, env_init, sys_init, env_safe, sys_safe, env_prog, sys_prog) #GR(1) specification created print specs.pretty() # # Controller synthesis # # The controller decides based on current variable values only, # without knowing yet the next values that environment variables take. # A controller with this information flow is known as Moore. specs.moore = True # Ask the synthesizer to find initial values for system variables # that, for each initial values that environment variables can # take and satisfy `env_init`, the initial state satisfies # `env_init /\ sys_init`. specs.qinit = '\E \A' # i.e., "there exist sys_vars: forall sys_vars" #assert not specs.sys_safe ctrl = synth.synthesize('gr1c', specs) assert ctrl is not None, 'unrealizable' #print ctrl #print ctrl #if not ctrl.save('gr1.png'): # print(ctrl) #print ctrl #print specs.pretty() dumpsmach.write_python_case("followMeController.py", ctrl, classname="FollowCtrl")
# sys_safe |= {'((env1 = '+str(iter2+iter1*dim)+') && (loc = '+str(iter2+1+iter1*dim)+')) -> X !(loc = '+str(iter2+iter1*dim)+')'} # sys_safe |= {'((env1 = '+str(iter2+1+iter1*dim)+') && (loc = '+str(iter2+iter1*dim)+')) -> X !(loc = '+str(iter2+1+iter1*dim)+')'} # if(iter1 < dim-1): # sys_safe |= {'((env1 = '+str(iter2+iter1*dim)+') && (loc = '+str(iter2+(iter1+1)*dim)+')) -> X !(loc = '+str(iter2+iter1*dim)+')'} # sys_safe |= {'((env1 = '+str(iter2+(iter1+1)*dim)+') && (loc = '+str(iter2+iter1*dim)+')) -> X !(loc = '+str(iter2+(iter1+1)*dim)+')'} specs = spec.GRSpec(env_vars,sys_vars,env_init,sys_init,env_safe,sys_safe,env_prog,sys_prog) #GR(1) specification created # # Controller synthesis # # The controller decides based on current variable values only, # without knowing yet the next values that environment variables take. # A controller with this information flow is known as Moore. specs.moore = True # Ask the synthesizer to find initial values for system variables # that, for each initial values that environment variables can # take and satisfy `env_init`, the initial state satisfies # `env_init /\ sys_init`. specs.qinit = '\E \A' # i.e., "there exist sys_vars: forall sys_vars" ctrl = synth.synthesize('gr1c',specs) assert ctrl is not None, 'unrealizable' #if not ctrl.save('gr1.png'): # print(ctrl) print ctrl #print specs.pretty() dumpsmach.write_python_case("simpleController.py", ctrl, classname="SquareCtrl")
def create_w_specs_all_init_cond(current_horizon, x_goal_loc, y_goal_loc, w_part, transition_part, dimension_x, dimension_y): # Don't synthesize for corner w regions (i.e. w region that's only a corner) that can't be fulfilled (... so ugly) # Note: Better way of doing this would be to not add corner regions to w_part... if (w_part[current_horizon] == [(dimension_x, dimension_y, 1)] or w_part[current_horizon] == [(dimension_x, dimension_y, 2)] or w_part[current_horizon] == [(dimension_x, dimension_y, 3)] or w_part[current_horizon] == [(dimension_x, dimension_y, 4)] or w_part[current_horizon] == [(dimension_x, 1, 1)] or w_part[current_horizon] == [(dimension_x, 1, 2)] or w_part[current_horizon] == [(dimension_x, 1, 3)] or w_part[current_horizon] == [(dimension_x, 1, 4)] or w_part[current_horizon] == [(1, dimension_y, 1)] or w_part[current_horizon] == [(1, dimension_y, 2)] or w_part[current_horizon] == [(1, dimension_y, 3)] or w_part[current_horizon] == [(1, dimension_y, 4)] or w_part[current_horizon] == [(1, 1, 1)] or w_part[current_horizon] == [(1, 1, 2)] or w_part[current_horizon] == [(1, 1, 3)] or w_part[current_horizon] == [(1, 1, 4)]): return # Create FTS and actions sys_auto = transys.FTS() sys_auto.sys_actions.add_from({'Stop', 'Go'}) # Fake AP's to enable all specs related to base and goal position sys_auto.states.add_from(['FAKE']) sys_auto.atomic_propositions.add_from({'Base', 'GoalPos'}) sys_auto.states['FAKE']['ap'] |= {'Base', 'GoalPos'} # Add all AP's for the transition space, including those tied to 'Base' and 'GoalPos' if present in transition space for locat in transition_part[current_horizon]: add_ap_sub = 'Pos' + str(locat[0]) + '_' + str(locat[1]) + 'Ori' + str( locat[2]) sys_auto.states.add_from([add_ap_sub]) if locat[0] == 2 and locat[ 1] == 2: # TODO add some global indicator of the base location sys_auto.states[add_ap_sub]['ap'] |= {'Base'} if locat[0] == x_goal_loc and locat[1] == y_goal_loc: sys_auto.states[add_ap_sub]['ap'] |= {'GoalPos'} # Initial condition, empty set sys_auto_init = set() #print(transition_part[current_horizon]) #print(w_part[current_horizon]) #input('uhmmm...') # NOTE: that current_horizon is 1, 2, 3, ... # Create all transitions through brute force method of checking existence of locations in the transition region next # to every starting point, dependent on the orientation. This is ran on transition region and inclusion in w region # is checked in creating transitions. This is because all w regions are contained in the transition region, and # transitions from a w region are different than those form just transition regions for locat in transition_part[current_horizon]: init = 'Pos' + str(locat[0]) + '_' + str(locat[1]) + 'Ori' + str( locat[2]) if locat in w_part[current_horizon]: sys_auto.transitions.add_comb({init}, {init}, sys_actions="Stop") # Transitions allowed if orientation is up if locat[2] == 1: if (locat[0], locat[1] + 1, 1) in transition_part[current_horizon]: endloc = 'Pos' + str( locat[0]) + '_' + str(locat[1] + 1) + 'Ori' + str(1) sys_auto.transitions.add_comb({init}, {endloc}, sys_actions="Go") if (locat[0] + 1, locat[1] + 1, 2) in transition_part[current_horizon]: endloc = 'Pos' + str(locat[0] + 1) + '_' + str(locat[1] + 1) + 'Ori' + str(2) sys_auto.transitions.add_comb({init}, {endloc}, sys_actions="Go") if (locat[0] - 1, locat[1] + 1, 4) in transition_part[current_horizon]: endloc = 'Pos' + str(locat[0] - 1) + '_' + str(locat[1] + 1) + 'Ori' + str(4) sys_auto.transitions.add_comb({init}, {endloc}, sys_actions="Go") # Transitions allowed if orientation is right elif locat[2] == 2: if (locat[0] + 1, locat[1], 2) in transition_part[current_horizon]: endloc = 'Pos' + str(locat[0] + 1) + '_' + str( locat[1]) + 'Ori' + str(2) sys_auto.transitions.add_comb({init}, {endloc}, sys_actions="Go") if (locat[0] + 1, locat[1] + 1, 1) in transition_part[current_horizon]: endloc = 'Pos' + str(locat[0] + 1) + '_' + str(locat[1] + 1) + 'Ori' + str(1) sys_auto.transitions.add_comb({init}, {endloc}, sys_actions="Go") if (locat[0] + 1, locat[1] - 1, 3) in transition_part[current_horizon]: endloc = 'Pos' + str(locat[0] + 1) + '_' + str(locat[1] - 1) + 'Ori' + str(3) sys_auto.transitions.add_comb({init}, {endloc}, sys_actions="Go") # Transitions allowed if orientation is down elif locat[2] == 3: if (locat[0], locat[1] - 1, 3) in transition_part[current_horizon]: endloc = 'Pos' + str( locat[0]) + '_' + str(locat[1] - 1) + 'Ori' + str(3) sys_auto.transitions.add_comb({init}, {endloc}, sys_actions="Go") if (locat[0] + 1, locat[1] - 1, 2) in transition_part[current_horizon]: endloc = 'Pos' + str(locat[0] + 1) + '_' + str(locat[1] - 1) + 'Ori' + str(2) sys_auto.transitions.add_comb({init}, {endloc}, sys_actions="Go") if (locat[0] - 1, locat[1] - 1, 4) in transition_part[current_horizon]: endloc = 'Pos' + str(locat[0] - 1) + '_' + str(locat[1] - 1) + 'Ori' + str(4) sys_auto.transitions.add_comb({init}, {endloc}, sys_actions="Go") # Transitions allowed if orientation is left elif locat[2] == 4: if (locat[0] - 1, locat[1], 4) in transition_part[current_horizon]: endloc = 'Pos' + str(locat[0] - 1) + '_' + str( locat[1]) + 'Ori' + str(4) sys_auto.transitions.add_comb({init}, {endloc}, sys_actions="Go") if (locat[0] - 1, locat[1] + 1, 1) in transition_part[current_horizon]: endloc = 'Pos' + str(locat[0] - 1) + '_' + str(locat[1] + 1) + 'Ori' + str(1) sys_auto.transitions.add_comb({init}, {endloc}, sys_actions="Go") if (locat[0] - 1, locat[1] - 1, 3) in transition_part[current_horizon]: endloc = 'Pos' + str(locat[0] - 1) + '_' + str(locat[1] - 1) + 'Ori' + str(3) sys_auto.transitions.add_comb({init}, {endloc}, sys_actions="Go") # Create possible transitions for initial conditions in only the transition region. Only transitions are # staying still, assigned to both action groups. This works because in implementation the controllers will # switch to the next horizon here else: sys_auto.transitions.add_comb({init}, {init}, sys_actions="Stop") sys_auto.transitions.add_comb({init}, {init}, sys_actions="Go") # Begin generating the specifications!! # Create the additional environmental variables, including signal for w region next to goal env_auto_vars = {'StopSignal', 'Fire'} if current_horizon == 1: env_auto_vars |= {'SyncSignal'} # Create the environment specifications, including progress related to sync signal next to goal env_auto_safe = set() env_auto_init = {'!StopSignal', '!Fire'} env_auto_prog = {'!StopSignal', '!Fire'} if current_horizon == 1: env_auto_prog |= {'SyncSignal'} # System variables and safety specification empty sets sys_auto_vars = set() sys_auto_safe = set() # Create stop signal requirements # TODO This should be changed to present actions... sys_auto_safe |= {'(StopSignal&&!Fire)->(X(sys_actions = "Stop"))'} sys_auto_safe |= {'(!(StopSignal&&!Fire))->(X(sys_actions = "Go"))'} # Add relevant phi variables to safety (i.e. all phi contained within this region). Never enter phi locations phi = '' for locat in transition_part[current_horizon]: state = 'Pos' + str(locat[0]) + '_' + str(locat[1]) + 'Ori' + str( locat[2]) for names in phi_states: if state == names: phi = phi + '!(loc = "' + names + '")&&' phi = phi + 'True' sys_auto_safe |= {phi} # Empty initial progress sys_auto_prog = set() # Display progress statement to user print(('Beginning synthesis of W' + str(current_horizon) + ' for goal (' + str(x_goal_loc) + ',' + str(y_goal_loc) + ')!')) # Cycle through all initial conditions in this w region for synthesizing controller for idxn, locat in enumerate(w_part[current_horizon]): locat_sub = locat #if locat == (9, 8, 3): # print('here') # input('wait...') # Create checks to see if current position is viable initial condition current_state = 'Pos' + str(locat_sub[0]) + '_' + str( locat_sub[1]) + 'Ori' + str(locat_sub[2]) # Run through names in phi_states to check if it's included indicator = 0 for names in phi_states: if current_state == names: indicator = 1 # If current state passed, then add to initial condition and synthesize. Otherwise, move to next I.C. if indicator == 0: sys_auto_init = {'(loc = "' + current_state + '")'} else: continue # Create the progress statements and synthesize. Progress statements differ depending on current horizon # For horizon W1 if current_horizon == 1: # This section is the 'sync' version of specs, which is just the normal "correct" version print('Sync synthesis for ' + current_state) # Start timer for synthesis start_time = time.time() # Spec just states that the sync signal implies goal position is there sync_spec = '(SyncSignal)->GoalPos' sys_auto_prog = {sync_spec} # Create the GR spec for all the generated env and sys specs specs_final_sync = spec.GRSpec(env_auto_vars, sys_auto_vars, env_auto_init, sys_auto_init, env_auto_safe, sys_auto_safe, env_auto_prog, sys_auto_prog) # Synthesizer attributes specs_final_sync.moore = True option = 'omega' specs_final_sync.qinit = '\E \A' # synthesizer should find initial system values that satisfy # `env_init /\ sys_init` and work, for every environment variable # initial values that satisfy `env_init`. # SYNTHESIZE!!! ctrl_final_sync = synth.synthesize(option, specs_final_sync, env=None, sys=sys_auto, ignore_sys_init=True) # Failure results in adjustments to the horizon related to current I.C. if ctrl_final_sync is None: print('Failed to synthesize ' + current_state + ', moving to next w_part and transition_part') w_part[current_horizon + 1].append(locat) if locat not in transition_part[current_horizon + 1]: transition_part[current_horizon + 1].append(locat) w_part[current_horizon][idxn] = None transition_part[current_horizon].remove(locat) #if locat == (9, 8, 2): # print('here') # print(w_part[current_horizon]) # input('wait...') # Stopwatch and print synth_time = time.time() - start_time print(synth_time) # Write controller to relevant location if it synthesized filename = 'ctrls/Goal' + str(x_goal_loc) + '_' + str(y_goal_loc) + '/G' + str(x_goal_loc) + '_' + \ str(y_goal_loc) + current_state + '.py' #'_W' + str(current_horizon) + if ctrl_final_sync is not None: dumpsmach.write_python_case(filename, ctrl_final_sync) #if locat == (9, 8, 2): # print('here') # print(w_part[current_horizon]) # input('wait...') # All other horizons from the first one (>= W2) else: print('Synthesis for ' + current_state) # Start timer for synthesis start_time = time.time() # Generate progress to any area of transition region that aren't in the w region (inner layer) spec_inter = '((' for locat2 in transition_part[current_horizon]: if locat2 not in w_part[current_horizon]: locations = 'Pos' + str(locat2[0]) + '_' + str( locat2[1]) + 'Ori' + str(locat2[2]) spec_inter = spec_inter + 'loc = "' + locations + '")||(' # Finish tail end of progress spec (false is there to wrap up string generated by loop) spec_inter = spec_inter + 'False))' sys_auto_prog |= {spec_inter} # Create the GR spec for all the generated env and sys specs specs_inter = spec.GRSpec(env_auto_vars, sys_auto_vars, env_auto_init, sys_auto_init, env_auto_safe, sys_auto_safe, env_auto_prog, sys_auto_prog) # Synthesizer attributes specs_inter.moore = True option = 'omega' specs_inter.qinit = '\E \A' # synthesizer should find initial system values that satisfy # `env_init /\ sys_init` and work, for every environment variable # initial values that satisfy `env_init`. # SYNTHESIZE!!! ctrl_inter = synth.synthesize(option, specs_inter, sys=sys_auto, ignore_sys_init=True) # Failure results in adjustments to the horizon related to current I.C. if ctrl_inter is None: print('Failed to synthesize ' + current_state + ', moving to next w_part and transition_part') w_part[current_horizon + 1].append(locat) if locat not in transition_part[current_horizon + 1]: transition_part[current_horizon + 1].append(locat) w_part[current_horizon][idxn] = None transition_part[current_horizon].remove(locat) # Stopwatch and print synth_time = time.time() - start_time print(synth_time) # Write controller to relevant location if it synthesized filename = 'ctrls/Goal' + str(x_goal_loc) + '_' + str(y_goal_loc) + '/G' + str(x_goal_loc) + '_' + \ str(y_goal_loc) + current_state + '.py' #'_W' + str(current_horizon) + if ctrl_inter is not None: dumpsmach.write_python_case(filename, ctrl_inter)
sys_prog |= {'stage = 0'} sys_prog |= {'stage = 3'} sys_safe |= {('((stage = 0) && (sa'+str((2*x)-1)+')) -> X (stage = 1)')} sys_safe |= {('((stage = 0) && (!sa'+str((2*x)-1)+')) -> X (stage = 0)')} sys_safe |= {('((stage = 1) && (sa'+str(2*x)+')) -> X (stage = 2)')} sys_safe |= {('((stage = 1) && (!sa'+str(2*x)+')) -> X (stage = 1)')} sys_safe |= {('((stage = 2) && (sa'+str((x*y) - 1)+')) -> X (stage = 3)')} sys_safe |= {('((stage = 2) && (!sa'+str((x*y) - 1)+')) -> X (stage = 2)')} sys_safe |= {('((stage = 3) && (sa'+str(0)+')) -> X (stage = 0)')} sys_safe |= {('((stage = 3) && (!sa'+str(0)+')) -> X (stage = 3)')} sys_safe |= specset specs = spec.GRSpec(env_vars, sys_vars, env_init, sys_init, env_safe, sys_safe, env_prog, sys_prog) ctrl = synth.synthesize('gr1c',specs, sys=sys) finish = time.clock() print finish - start dumpsmach.write_python_case("gr1controller"+str(x)+".py", ctrl, classname="ExampleCtrl") finish = time.clock() print finish - start #finish = time.clock() #print finish - start #print specs.pretty() #if not ctrl.save('discerete2.png'): # print(ctrl) #finish = time.clock() #print finish - start
def runPaperExample(exampleRun, ver='1', riskgt=17, energygt=0): # set initial variables if (exampleRun == 'test1'): ver = '1' riskgt = 17 energygt = 0 elif (exampleRun == 'test2'): ver = '2' riskgt = 17 energygt = 6 elif (exampleRun == 'test3'): ver = '3' riskgt = 16 energygt = 6 # set logfile import logging logging.basicConfig(filename='deliberative_action_planner_%s.log' % ver, level=logging.INFO, filemode='w') # level=logging.DEBUG logger = logging.getLogger(__name__) # Create a finite transition system sys_sws = transys.FTS() # system actions only, no (open) env. yet # add the states and actions #sys_sws.states.add_from(['s1','s2','s3','s4','s5']) for i in range(1, 5 + 1): sys_sws.states.add('s' + str(i)) #sys_sws.actions.add_from(['a12_1','a12_2','a23_1', 'a23_2', 'a15_1', 'a15_2', 'a14_1', 'a45_1', 'a35_1']) # then set up the transitions (state1, action1 -> state2) for numlist in [[1, 2, 2], [2, 3, 2], [1, 5, 2], [1, 4, 1], [4, 5, 1], [3, 5, 1]]: st1 = numlist[ 0] # [s"#1" loc1, s"#2" loc2, number of actions a"#1#2_#"] st2 = numlist[1] numactions = numlist[2] st1str = 's' + str(st1) st2str = 's' + str(st2) #sys_sws.states.add_from([st1str,st2str]) # could do this instead of above for i in range(1, numactions + 1): astr = 'a' + str(st1) + str(st2) + '_' + str(i) sys_sws.actions.add(astr) # could do this instead of above sys_sws.transitions.add(st1str, st2str, actions=astr) sys_sws.transitions.add(st2str, st1str, actions=astr) # then set up transitions for (state1, wait -> state1) sys_sws.actions.add('wait') for st1 in range(1, 5 + 1): st1str = 's' + str(st1) sys_sws.transitions.add(st1str, st1str, actions='wait') # set s1 as initial state initial_state_str = 's1' #initial_state_str = 's2' sys_sws.states.initial.add(initial_state_str) # This is what is visible to the outside world (and will go into synthesis method) print( sys_sws ) # show the Finite Transition System, make sure it was encoded properly sys_sws.save('deliberative_%sa.pdf' % ver) # save the visual diagram of the FTS, for same reason # sys_sws.save() shows all possible transitions between states according to actions print("Done saving deliberative_%sa.pdf" % ver) # # Environment variables and specification # # The environment can issue a park signal that the robot just respond # to by moving to the lower left corner of the grid. We assume that # the park signal is turned off infinitely often. # env_vars = set() # empty set env_init = set() # empty set env_prog = set() # empty set env_safe = set() # empty set # # System specification # # The system specification is that the robot should (repeatedly?) revisit # the rightmost spire (this is because there are no 'wait' or 'stay in same # state' actions currently). # does sys_vars actually use the "0" value? it doesn't seem to... # basically, looks like a "0" value pulls the value completely off the stack (as False?), in the 'atomic proposition' sense of things # so, we want to avoid using value=0 for this kind of stuff! ^_^ # note: for gr1c, lower bound must be zero (0) print("Writing up goals and such for system") print("Writing up sys vars and such for system") sys_vars = dict() sys_init = set() sys_prog = set() sys_safe = set() sys_init |= {'sys_actions=wait'} # start in wait mode goalstr = 's5' #goalstr = 's3' sys_prog |= {'loc=%s' % goalstr} # goal --> []<> (get to s5) sys_safe |= { 'loc=%s -> next(loc=%s)' % (goalstr, goalstr) } # then stay there forever # this didn't seem to work with the FTS before, now does for some reason, not sure what's going on... energylo = 0 energyhi = 20 sys_vars.update({'energy': (energylo, energyhi)}) sys_init |= {'energy=%d' % energyhi} sys_safe |= {'energy > %d' % energygt } # must keep fuel/energy usage above energygt risklo = 0 riskhi = 20 sys_vars.update({'risk': (risklo, riskhi)}) sys_init |= {'risk=%d' % riskhi} sys_safe |= {'risk > %d' % riskgt} # must keep risk usage above riskgt # 0 1 2 3 4 5 6 7 8 9 allactStr = [ 'a35_1', 'a23_1', 'a23_2', 'a12_1', 'a12_2', 'a15_2', 'a15_1', 'a45_1', 'a14_1', 'wait' ] alldropenergy = [4, 3, 6, 2, 3, 7, 6, 5, 3, 0] alldroprisk = [1, 4, 0, 2, 1, 1, 2, 0, 0, 0] for actStr, energydrop, riskdrop in zip(allactStr, alldropenergy, alldroprisk): #energystr = energyStr(energylo,energyhi,energydrop) energystr = dropStr('energy', energylo, energyhi, energydrop) sys_safe |= { 'sys_actions=%s -> (%s && (X(energy=0) <-> energy<=%d))' % (actStr, energystr, alldropenergy[i - 1]) } # wait action keeps energy at same level (no energy used) riskstr = dropStr('risk', risklo, riskhi, riskdrop) sys_safe |= { 'sys_actions=%s -> (%s && (X(risk=0) <-> risk<=%d))' % (actStr, riskstr, alldroprisk[i - 1]) } # wait action keeps energy at same level (no energy used) # 0 1 2 3 4 # atakepicture# alldropenergy2 = [0, 0, 0, 0, 0] alldroprisk2 = [0, 0, 0, 0, 0] for i in range(1, 5 + 1): # [1] atakepicture1,picAtS1Taken, ... actStr = 'atakepicture%d' % i energystr = dropStr('energy', energylo, energyhi, alldropenergy2[i - 1]) sys_safe |= { 'sys_actions=%s -> (%s && (X(energy=0) <-> energy<=%d))' % (actStr, energystr, alldropenergy2[i - 1]) } # wait action keeps energy at same level (no energy used) riskstr = dropStr('risk', risklo, riskhi, alldroprisk2[i - 1]) sys_safe |= { 'sys_actions=%s -> (%s && (X(risk=0) <-> risk<=%d))' % (actStr, riskstr, alldroprisk2[i - 1]) } # wait action keeps energy at same level (no energy used) actboolStr = 'picAtS%dTaken' % i locStr = 's%d' % i sys_sws.actions.add(actStr) sys_sws.transitions.add('s%d' % i, 's%d' % i, actions=actStr) sys_vars.update({actboolStr: 'boolean'}) sys_init |= {'!%s' % actboolStr} sys_safe |= { '(energy>%d && loc=%s && sys_actions=%s) -> X(%s)' % (alldropenergy2[i - 1], locStr, actStr, actboolStr) } sys_safe |= { '(energy<=%d && loc=%s && sys_actions=%s) -> X(energy=0)' % (alldropenergy2[i - 1], locStr, actStr) } sys_safe |= { '(sys_actions!=%s && !%s) -> (X(!%s))' % (actStr, actboolStr, actboolStr) } # don't allow other actions to arbitrarily set this to True sys_safe |= {'%s -> X(%s)' % (actboolStr, actboolStr) } # if picture is taken, 'stays' taken sys_prog |= {'picAtS2Taken'} # goal --> trying to take picture at s2 # 0 1 2 3 4 # atakesample# alldropenergy3 = [1, 1, 1, 1, 1] alldroprisk3 = [0, 0, 0, 0, 0] for i in range(1, 5 + 1): # [1] atakepicture1,picAtS1Taken, ... actStr = 'atakesample%d' % i energystr = dropStr('energy', energylo, energyhi, alldropenergy3[i - 1]) sys_safe |= { 'sys_actions=%s -> (%s && (X(energy=0) <-> energy<=%d))' % (actStr, energystr, alldropenergy3[i - 1]) } # wait action keeps energy at same level (no energy used) riskstr = dropStr('risk', risklo, riskhi, alldroprisk3[i - 1]) sys_safe |= { 'sys_actions=%s -> (%s && (X(risk=0) <-> risk<=%d))' % (actStr, riskstr, alldroprisk3[i - 1]) } # wait action keeps energy at same level (no energy used) actboolStr = 'samAtS%dTaken' % i locStr = 's%d' % i sys_sws.actions.add(actStr) sys_sws.transitions.add('s%d' % i, 's%d' % i, actions=actStr) sys_vars.update({actboolStr: 'boolean'}) sys_init |= {'!%s' % actboolStr} sys_safe |= { '(energy>%d && loc=%s && sys_actions=%s) -> X(%s)' % (alldropenergy3[i - 1], locStr, actStr, actboolStr) } sys_safe |= { '(energy<=%d && loc=%s && sys_actions=%s) -> X(energy=0)' % (alldropenergy3[i - 1], locStr, actStr) } sys_safe |= { '(sys_actions!=%s && !%s) -> (X(!%s))' % (actStr, actboolStr, actboolStr) } # don't allow other actions to arbitrarily set this to True sys_safe |= {'%s -> X(%s)' % (actboolStr, actboolStr) } # if sample is taken, 'stays' taken #sys_prog |= {'samAtS5Taken'} # goal --> trying to take sample at s5 # # after all sys_goal specs are written... # goal_conditions = '' for goalpieceStr in list(sys_prog): goal_conditions += goalpieceStr + ' && ' goal_conditions = goal_conditions[0:len(goal_conditions) - 4] # remove trailing ' && ' # set up stepcounter at the end of everything, after all sys_goal specs are written: steplo = 0 stephi = 8 # lower this number to try and force gr1c to be more efficient sys_vars.update({'stepCounter': (steplo, stephi)}) sys_init |= {'stepCounter=%d' % steplo} stepstr = riseStr('stepCounter', steplo, stephi, 1) sys_safe |= { '!(%s) -> %s' % (goal_conditions, stepstr) } # goal_conditions not met implies stepCounter increases by 1 each time stepstr = riseStr('stepCounter', steplo, stephi, 0) sys_safe |= { '(%s) -> %s' % (goal_conditions, stepstr) } # goal_conditions met implies stepCounter doesn't increase (any more) # then lower stephi to try and force gr1c to find a more efficient (shortest number of actions) solution sys_safe |= { 'stepCounter < %d' % (stephi) } # must keep counter below stephi; requires below that we stop counting steps after we finish all goals # add this in so we can tell when we're just doing extra stuff post-whatever sys_vars.update({'sysgoalsReached': 'boolean'}) sys_init |= {'!sysgoalsReached'} sys_safe |= {'!(%s) <-> !sysgoalsReached' % (goal_conditions) } # goal_conditions not met implies sysgoals(not_yet)Reached sys_safe |= {'(%s) <-> sysgoalsReached' % (goal_conditions) } # goal_conditions met implies sysgoalsReached # changes might've been made this far down, so show again... print( sys_sws ) # show the Finite Transition System, make sure it was encoded properly sys_sws.save('deliberative_%sb.pdf' % ver) # save the visual diagram of the FTS, for same reason print("Done saving deliberative_%sb.pdf" % ver) print("Creating spec for sys_sws system") # Create the specification specs = spec.GRSpec(env_vars=env_vars, sys_vars=sys_vars, env_init=env_init, sys_init=sys_init, env_safety=env_safe, sys_safety=sys_safe, env_prog=env_prog, sys_prog=sys_prog) print(specs.pretty()) # GRSpec(env_vars=None, sys_vars=None, env_init='', sys_init='', env_safety='', sys_safety='', env_prog='', sys_prog='') # (env_init & []env_safety & []<>env_prog_1 & []<>env_prog_2 & ...) # -> (sys_init & []sys_safety & []<>sys_prog_1 & []<>sys_prog_2 & ...) # # C{env_vars}: alias for C{input_variables} of L{LTL}, concerning variables that are determined by the environment # C{env_init}: a list of string that specifies the assumption about the initial state of the environment. # C{env_safety}: a list of string that specifies the assumption about the evolution of the environment state. # C{env_prog}: a list of string that specifies the justice assumption on the environment. # C{sys_vars}: alias for C{output_variables} of L{LTL}, concerning variables that are controlled by the system. # C{sys_init}: a list of string that specifies the requirement on the initial state of the system. # C{sys_safety}: a list of string that specifies the safety requirement. # C{sys_prog}: a list of string that specifies the progress requirement. print("Done creating spec for sys_sws system") # Controller synthesis # # At this point we can synthesize the controller using one of the available # methods. Here we make use of gr1c. # print("Synthesizing solution for sys_sws system") ctrl = synth.synthesize('gr1c', specs, sys=sys_sws) print("Done synthesizing solution for sys_sws system") print("Creating .png file for sys_sws system") if ctrl is None: print( "Got gr1c error, not attempting save =or= print-to-screen =or= MealyMachine dumpsmach" ) else: # Generate a graphical representation of the controller for viewing if not ctrl.save('deliberative_%s_sws.png' % ver): print("Couldn't save .png file, printing ctrl instead") print(ctrl) print("Done printing ctrl instead") print("Done creating .png file for sys_sws system") print("Writing MealyMachine out via dumpsmach") # ctrl is a MealyMachine from tulip import dumpsmach dumpsmach.write_python_case(filename='dumpsmachtest_dlap%s.py' % ver, M=ctrl, classname="TulipStrategy", start='Sinit') print("Done writing MealyMachine out to dumpsmachtest_dlap%s.py" % ver)
assert strategy is not None, 'unrealizable' # Generate a graphical representation of the controller for viewing, or a textual representation if pydot is missing. # if not strategy.save('test_eval_example_modified.png'): # print(strategy) # Writing strategy to file for elem in env_init: break elem = elem.strip('()').split() env0 = int(elem[2]) if (env0 == 2): print("2") dumpsmach.write_python_case("TE2_v2.py", strategy, classname="TE_ctrl_init2") elif (env0 == 3): print("3") dumpsmach.write_python_case("TE3_v2.py", strategy, classname="TE_ctrl_init3") elif (env0 == 6): print("6") dumpsmach.write_python_case("TE6_v2.py", strategy, classname="TE_ctrl_init6") elif (env0 == 7): print("7") dumpsmach.write_python_case("TE7_v2.py", strategy,
# Simple example of pedestrian crossing street: Ncar = 5 Nped = 3 Vhigh = 1 Vlow = 0 xcar = 1 vcar = Vhigh xped = 3 xcross_start = 3 assert (Nped + xcross_start - 1 <= Ncar) # When a pedestrian is observed: env_vars, sys_vars, env_init, sys_init, env_safe, sys_safe, env_prog, sys_prog = pedestrianK( Ncar, Nped, xcar, vcar, Vlow, Vhigh, xped, xcross_start) Kped = design_C(env_vars, sys_vars, env_init, sys_init, env_safe, sys_safe, env_prog, sys_prog) write_python_case("ped_controller.py", Kped) # When something other than a pedestrian is observed: env_vars, sys_vars, env_init, sys_init, env_safe, sys_safe, env_prog, sys_prog = not_pedestrianK( Ncar, Nped, xcar, vcar, Vlow, Vhigh, xped, xcross_start) Knot_ped = design_C(env_vars, sys_vars, env_init, sys_init, env_safe, sys_safe, env_prog, sys_prog) write_python_case("not_ped_controller.py", Knot_ped) # When nothing is observed: env_vars, sys_vars, env_init, sys_init, env_safe, sys_safe, env_prog, sys_prog = emptyK( Ncar, Nped, xcar, vcar, Vlow, Vhigh, xped, xcross_start) Kempty = design_C(env_vars, sys_vars, env_init, sys_init, env_safe, sys_safe, env_prog, sys_prog) write_python_case("empty_controller.py", Kempty)
specs.moore = False # Ask the synthesizer to find initial values for system variables # that, for each initial values that environment variables can # take and satisfy `env_init`, the initial state satisfies # `env_init /\ sys_init`. specs.qinit = '\E \A' # i.e., "there exist sys_vars: forall sys_vars" ctrl = synth.synthesize('gr1c', specs) assert ctrl is not None, 'unrealizable' #if not ctrl.save('gr1.png'): # print(ctrl) #print ctrl #print specs.pretty() dumpsmach.write_python_case("followMeController_10_2_0_0_obs.py", ctrl, classname="FollowMeCtrl_10_obs") # from tulip import spec, synth , dumpsmach # import cPickle as pickle # import sys # sys.setrecursionlimit(150000000) # # dim = 50 # # number_cell = dim*dim -1 # # sys_size = 2 # # env_size = 2 # # margin = 5
# []<> X0 && [](searchTheEgg -> <>X7 && <>X3 && <>X6) && [](!searchTheEgg -> <>X0) # # Since this specification is not in GR(1) form, we introduce three # environment variables X7reach X6reach X3 reach that are initialized to True and the specification : # 1. [](searchTheEgg -> <>X7 && <>X3 && <>X6) # becomes : # 1.1 [](X (X7reach) <-> (X7)) || (X7reach && !searchTheEgg), # 1.2 [](X (X6reach) <-> (X6)) || (X6reach && !searchTheEgg), # 1.3 [](X (X3reach) <-> (X3)) || (X3reach && !searchTheEgg), # # Augment the system description to make it GR(1) sys_init = {'X7reach', 'X6reach', 'X3reach', 'batteryLevel = 1', 'quadrotorLocation = 0', 'eggLocationVisited = 0', '!eggCoordinatesSent'} #does not work with 2x sys_init ={...} sys_safe |= { '(X (X7reach) <-> (quadrotorLocation=7)) || (X7reach && !searchTheEgg)', '(X (X6reach) <-> (quadrotorLocation=6)) || (X6reach && !searchTheEgg)', '(X (X3reach) <-> (quadrotorLocation=3)) || (X3reach && !searchTheEgg)', } sys_prog |= {'eggCoordinatesSent'} #send coordinates to the Segway # Create a GR(1) specification specs = spec.GRSpec(env_vars, sys_vars, env_init, sys_init, env_safe, sys_safe, env_prog, sys_prog) specs.moore = True specs.qinit = '\E \A' # Controller synthesis strategy = synth.synthesize('omega', specs) assert strategy is not None, 'unrealizable' dumpsmach.write_python_case("quadrotorController.py", strategy, classname="controller") machines.random_run(strategy, N=100)