def goal_test(self, state: str) -> bool: kb = PropKB() kb.tell(decode_state(state, self.state_map).pos_sentence()) for clause in self.goal: if clause not in kb.clauses: return False return True
def result(self, state: str, action: Action): """ Return the state that results from executing the given action in the given state. The action must be one of self.actions(state). :param state: state entering node :param action: Action applied :return: resulting state after action """ # TODO implement prev_state = decode_state(state, self.state_map) new_state = FluentState([], []) for fluent in prev_state.pos: if fluent not in action.effect_rem: new_state.pos.append(fluent) for fluent in prev_state.neg: if fluent not in action.effect_add: new_state.neg.append(fluent) for fluent in action.effect_add: if fluent not in new_state.pos: new_state.pos.append(fluent) for fluent in action.effect_rem: if fluent not in new_state.neg: new_state.neg.append(fluent) return encode_state(new_state, self.state_map)
def h_ignore_preconditions(self, node: Node): """This heuristic estimates the minimum number of actions that must be carried out from the current state in order to satisfy all of the goal conditions by ignoring the preconditions required for an action to be executed. """ # TODO implement (see Russell-Norvig Ed-3 10.2.3 or Russell-Norvig Ed-2 11.2) state=node.state fluent_state =decode_state(state, self.state_map) goal = self.goal remaining = set(goal) - set(fluent_state.pos) action_list = self.actions_list count = 0 while len(remaining)>0: most_effects = 0 for action in action_list: if len(remaining & set(action.effect_add)) > most_effects: most_effects = len(remaining & set(action.effect_add)) best_action = action count+=1 remaining = remaining - set(best_action.effect_add) return count
def goal_test(self, state: str) -> bool: """ Test the state to see if goal is reached :param state: str representing state :return: bool """ kb = PropKB() kb.tell(decode_state(state, self.state_map).pos_sentence()) for clause in self.goal: if clause not in kb.clauses: return False return True
def actions(self, state: str) -> list: """ Return the actions that can be executed in the given state. :param state: str state represented as T/F string of mapped fluents (state variables) e.g. 'FTTTFF' :return: list of Action objects """ # TODO implement possible_actions = [] decoded_state = decode_state(state, self.state_map) ds_pos = decoded_state.pos ds_neg = decoded_state.neg for action in self.actions_list: valid = True # Check if action is valid in positive preconditions for pos_precondition in action.precond_pos: if pos_precondition not in ds_pos: valid = False break # Check if action is valid in positive preconditions for neg_precondition in action.precond_neg: if neg_precondition not in ds_neg: valid = False break if valid: possible_actions.append(action) # possible_actions = [] # kb = PropKB() # kb.tell(decode_state(state, self.state_map).pos_sentence()) # # for action in self.actions_list: # action_vaild = True # for pos_precondition in action.precond_pos: # if pos_precondition in kb.clauses: # action_vaild = False # break # # #if action_vaild: # for neg_precondition in action.precond_neg: # if neg_precondition in kb.clauses: # action_vaild = False # break # # if action_vaild: # possible_actions.append(action) return possible_actions
def h_ignore_preconditions(self, node: Node): ''' This heuristic estimates the minimum number of actions that must be carried out from the current state in order to satisfy all of the goal conditions by ignoring the preconditions required for an action to be executed. ''' count = 0 kb = PropKB() kb.tell(decode_state(node.state, self.state_map).pos_sentence()) for clause in self.goal: if clause not in kb.clauses: count += 1 return count
def h_ignore_preconditions(self, node: Node): """This heuristic estimates the minimum number of actions that must be carried out from the current state in order to satisfy all of the goal conditions by ignoring the preconditions required for an action to be executed. """ # TODO implement (see Russell-Norvig Ed-3 10.2.3 or Russell-Norvig Ed-2 11.2) count = 0 kb = PropKB() kb.tell(decode_state(node.state, self.state_map).pos_sentence()) for clause in self.goal: if clause not in kb.clauses: count = count + 1 return count
def h_ignore_preconditions(self, node: Node): """This heuristic estimates the minimum number of actions that must be carried out from the current state in order to satisfy all of the goal conditions by ignoring the preconditions required for an action to be executed. """ # TODO implement (see Russell-Norvig Ed-3 10.2.3 or Russell-Norvig Ed-2 11.2) tf_fluents = decode_state(node.state, self.state_map) pos_only_list = tf_fluents.pos count = 0 for pos in pos_only_list: if pos in self.goal: count += 1 return len(self.goal) - count
def actions(self, state: str) -> list: # of Action possible_actions = [] kb = PropKB() kb.tell(decode_state(state, self.state_map).pos_sentence()) for action in self.actions_list: is_possible = True for clause in action.precond_pos: if clause not in kb.clauses: is_possible = False for clause in action.precond_neg: if clause in kb.clauses: is_possible = False if is_possible: possible_actions.append(action) return possible_actions
def result(self, state: str, action: Action): """ Return the state that results from executing the given action in the given state. The action must be one of self.actions(state). :param state: state entering node :param action: Action applied :return: resulting state after action """ fluent_state=decode_state(state, self.state_map) pos = [x for x in (fluent_state.pos + action.effect_add) if x not in action.effect_rem] neg = [x for x in (fluent_state.neg + action.effect_rem) if x not in action.effect_add] new_state = FluentState(pos, neg) return encode_state(new_state, self.state_map)
def result(self, state: str, action: Action): new_state = FluentState([], []) old_state = decode_state(state, self.state_map) for fluent in old_state.pos: if fluent not in action.effect_rem: new_state.pos.append(fluent) for fluent in action.effect_add: if fluent not in new_state.pos: new_state.pos.append(fluent) for fluent in old_state.neg: if fluent not in action.effect_add: new_state.neg.append(fluent) for fluent in action.effect_rem: if fluent not in new_state.neg: new_state.neg.append(fluent) return encode_state(new_state, self.state_map)
def actions(self, state: str) -> list: """ Return the actions that can be executed in the given state. :param state: str state represented as T/F string of mapped fluents (state variables) e.g. 'FTTTFF' :return: list of Action objects """ possible_actions = [] fluent_state=decode_state(state, self.state_map) for action in self.get_actions(): if set(fluent_state.pos).issuperset(set(action.precond_pos)) and set(fluent_state.neg).issuperset(set(action.precond_neg)): possible_actions.append(action) return possible_actions
def __init__(self, problem: Problem, state: str, serial_planning=True): """ :param problem: PlanningProblem (or subclass such as AirCargoProblem or HaveCakeProblem) :param state: str (will be in form TFTTFF... representing fluent states) :param serial_planning: bool (whether or not to assume that only one action can occur at a time) Instance variable calculated: fs: FluentState the state represented as positive and negative fluent literal lists all_actions: list of the PlanningProblem valid ground actions combined with calculated no-op actions s_levels: list of sets of PgNode_s, where each set in the list represents an S-level in the planning graph a_levels: list of sets of PgNode_a, where each set in the list represents an A-level in the planning graph """ self.problem = problem self.fs = decode_state(state, problem.state_map) self.serial = serial_planning self.all_actions = self.problem.actions_list + self.noop_actions(self.problem.state_map) self.s_levels = [] self.a_levels = [] self.create_graph()
def __init__(self, problem: Problem, state: str, serial_planning=True): ''' :param problem: PlanningProblem (or subclass such as AirCargoProblem or HaveCakeProblem) :param state: str (will be in form TFTTFF... representing fluent states) :param serial_planning: bool (whether or not to assume that only one action can occur at a time) Instance variable calculated: fs: FluentState the state represented as positive and negative fluent literal lists all_actions: list of the PlanningProblem valid ground actions combined with calculated no-op actions s_levels: list of sets of PgNode_s, where each set in the list represents an S-level in the planning graph a_levels: list of sets of PgNode_a, where each set in the list represents an A-level in the planning graph ''' self.problem = problem self.fs = decode_state(state, problem.state_map) self.serial = serial_planning self.all_actions = self.problem.actions_list + self.noop_actions( self.problem.state_map) self.s_levels = [] self.a_levels = [] self.create_graph()
def h_ignore_preconditions(self, node: Node): """This heuristic estimates the minimum number of actions that must be carried out from the current state in order to satisfy all of the goal conditions by ignoring the preconditions required for an action to be executed. """ kb = PropKB() decoded = decode_state(node.state, self.state_map) kb.tell(decoded.pos_sentence()) current_clauses = kb.clauses # Russell-Norvig 382: "Almost implies the number of steps required to solve a relaxed problem # is the number of unsatisfied goals" # following gets the number of goal clauses not satisfied, # works for independent goals # ref: https://ai-nd.slack.com/archives/C3TPR3RCG/p1502854124000011 unsatified_goals = [ goal_clause for goal_clause in self.goal if goal_clause not in current_clauses ] return len(unsatified_goals)
def actions(self, state: str) -> list: """ Return the actions that can be executed in the given state. :param state: str state represented as T/F string of mapped fluents (state variables) e.g. 'FTTTFF' :return: list of Action objects """ # TODO implement possible_actions = [] kb = PropKB() kb.tell(decode_state(state, self.state_map).pos_sentence()) for action in self.actions_list: if all([c in kb.clauses for c in action.precond_pos]) and \ all([c not in kb.clauses for c in action.precond_neg]): possible_actions.append(action) return possible_actions
def h_ignore_preconditions(self, node: Node): """This heuristic estimates the minimum number of actions that must be carried out from the current state in order to satisfy all of the goal conditions by ignoring the preconditions required for an action to be executed. """ # TODO implement (see Russell-Norvig Ed-3 10.2.3 or Russell-Norvig Ed-2 # 11.2) count = 0 #decoding the current state and adding only the positive clauses propos_logic_knowledgebase = PropKB() propos_logic_knowledgebase.tell( decode_state(node.state, self.state_map).pos_sentence()) for cl in self.goal: if (cl not in propos_logic_knowledgebase.clauses): count += 1 return count
def h_ignore_preconditions(self, node: Node): """This heuristic estimates the minimum number of actions that must be carried out from the current state in order to satisfy all of the goal conditions by ignoring the preconditions required for an action to be executed. """ # TODO implement (see Russell-Norvig Ed-3 10.2.3 or Russell-Norvig Ed-2 11.2) # Get a handle to our knowledge base of logical expressions (propositional logic) kb = PropKB() # Add the current state's positive sentence's clauses to the propositional logic KB kb.tell(decode_state(node.state, self.state_map).pos_sentence()) # Use a slightly modified version of the goal_test() fn count = 0 for clause in self.goal: if clause not in kb.clauses: count += 1 return count
def result(self, state: str, action: Action): """ Return the state that results from executing the given action in the given state. The action must be one of self.actions(state). :param state: state entering node :param action: Action applied :return: resulting state after action """ state = decode_state(state, self.state_map) for effect_rem in action.effect_rem: state.pos.remove(effect_rem) state.neg.append(effect_rem) for effect_add in action.effect_add: state.pos.append(effect_add) state.neg.remove(effect_add) return encode_state(state, self.state_map)
def h_ignore_preconditions(self, node: Node): """This heuristic estimates the minimum number of actions that must be carried out from the current state in order to satisfy all of the goal conditions by ignoring the preconditions required for an action to be executed. """ # TODO implement (see Russell-Norvig Ed-3 10.2.3 or Russell-Norvig Ed-2 11.2) count = 0 # print("\nh_ignore_preconditions") # print(self.goal) # print(node.state) if self.goal_test(node.state): return 0 else: kb = PropKB() kb.tell(decode_state(node.state, self.state_map).pos_sentence()) for clause in self.goal: if clause not in kb.clauses: count += 1 return count
def h_ignore_preconditions(self, node: Node): """This heuristic estimates the minimum number of actions that must be carried out from the current state in order to satisfy all of the goal conditions by ignoring the preconditions required for an action to be executed. """ # TODO implement (see Russell-Norvig Ed-3 10.2.3 or Russell-Norvig Ed-2 11.2) #count the no of goal conditions in possible actions and not in current state """ posactioncount = 0 posactions = self.actions(node.state) for action in posactions: for clause in self.goal: if clause not in kb.clauses: if clause in action.precond_pos: posactioncount += 1 return posactioncount This is taking about 30secs for P2 and 139 secs for P3 """ """ from forums figure out how many of the goal states are not yet satisfied in the current state. Because the number of unsatisfied goals equals the minimum number of actions you would need to take to satisfy them all. -- consider only pos conditions -- based on goal state """ count = 0 kb = PropKB() kb.tell(decode_state(node.state, self.state_map).pos_sentence()) for clause in self.goal: if clause not in kb.clauses: count += 1 return count
def actions(self, state: str) -> list: """ Return the actions that can be executed in the given state. :param state: str state represented as T/F string of mapped fluents (state variables) e.g. 'FTTTFF' :return: list of Action objects """ #Actions contained in self.actions_list represent all actions (load, #unload and fly) for all possible states of the problem. We want to #check which of this actions are possible for an specific state. #Initialize the list of possible actions that should be returned possible_actions = [] #Create an instance from the Knowledge Base from aimacode.logic kb = PropKB() #Read the positive statements of the state provided. This is enough #because actions are binary, either positive of negative, so checking #if they are not positive is the same as find if they are negative kb.tell(decode_state(state, self.state_map).pos_sentence()) #For every action check if it is compatible with the state given for action in self.actions_list: is_possible = True #Check that conditions that should be true are in the kb for clause in action.precond_pos: if clause not in kb.clauses: is_possible = False break #Check that conditions that should not be true are not in the kb for clause in action.precond_neg: if clause in kb.clauses: is_possible = False break if is_possible: possible_actions.append(action) return possible_actions
def h_ignore_preconditions(self, node: Node): ''' This heuristic estimates the minimum number of actions that must be carried out from the current state in order to satisfy all of the goal conditions by ignoring the preconditions required for an action to be executed. ''' # Assume that the maximum number of steps without preconditions is the # number of conditions in the goal state. maxSteps = self.goal.__len__() temp_pos = decode_state(node.state, self.state_map).pos # When an expression is already in a goal state, reduce the maxSteps # by one. This ensures that only necessary actions are counted. for expression in self.goal: if expression in temp_pos: maxSteps -= 1 return maxSteps
def h_ignore_preconditions(self, node: Node): """This heuristic estimates the minimum number of actions that must be carried out from the current state in order to satisfy all of the goal conditions by ignoring the preconditions required for an action to be executed. """ count = 0 goal = self.goal #list of goal fluents state_fluents = decode_state(node.state, self.state_map) fluents_left = set(goal) - set(state_fluents.pos) #we relax the actions by removing all preconditions and all effects #except those that are literals in the goal for action in self.actions_list: if action.effect_add[0] in fluents_left: #if effect matches goal fluents_left = set(fluents_left) - set(action.effect_add) count += 1 if not fluents_left: return count #we count the minimum number of actions #required such that the union of those actions’ effects satisfies the goal return None
def result(self, state: str, action: Action): """ Return the state that results from executing the given action in the given state. The action must be one of self.actions(state). :param state: state entering node :param action: Action applied :return: resulting state after action """ fluent_state = decode_state(state, self.state_map) new_pos = set(fluent_state.pos) new_pos = new_pos.difference(action.effect_rem) new_pos = new_pos.union(action.effect_add) new_neg = set(fluent_state.neg) new_neg = new_neg.difference(action.effect_add) new_neg = new_neg.union(action.effect_rem) new_state = FluentState(list(new_pos), list(new_neg)) return encode_state(new_state, self.state_map)
def h_ignore_preconditions(self, node: Node): ''' This heuristic estimates the minimum number of actions that must be carried out from the current state in order to satisfy all of the goal conditions by ignoring the preconditions required for an action to be executed. ''' # implement (see Russell-Norvig Ed-3 10.2.3 or Russell-Norvig Ed-2 11.2) count = 0 ''' The minimum number of actions needed to satisfy all goals: Check how many of the goal states are not yet satisfied in the current state. ''' pos = decode_state(node.state, self.state_map).pos goal = self.goal count = len(goal) - len(set(pos).intersection(goal)) return count
def actions(self, state: str) -> list: """ Return the actions that can be executed in the given state. :param state: str state represented as T/F string of mapped fluents (state variables) e.g. 'FTTTFF' :return: list of Action objects """ # TODO implement # self.actions_list # Action.check_precond (kb, args) possible_actions = [] kb = PropKB() kb.tell(decode_state(state, self.state_map).pos_sentence()) for action in self.actions_list: if action.check_precond(kb, action.args): possible_actions.append(action) return possible_actions
def h_ignore_preconditions(self, node: Node): ''' This heuristic estimates the minimum number of actions that must be carried out from the current state in order to satisfy all of the goal conditions by ignoring the preconditions required for an action to be executed. ''' # implement (see Russell-Norvig Ed-3 10.2.3 or Russell-Norvig Ed-2 11.2) # print("*****") # print(node.state) # print(self.goal) # print(decode_state(node.state, self.state_map).pos) # print("*****") count = 0 # for each goal for g in self.goal: # check if it is NOT satisfied in the node's fluent positives if g not in decode_state(node.state, self.state_map).pos: count += 1 return count
def actions(self, state: str) -> list: possible_actions = [] kb = PropKB() kb.tell(decode_state(state, self.state_map).pos_sentence()) for action in self.actions_list: possible = True for clause in action.precond_pos: if clause not in kb.clauses: possible = False for clause in action.precond_neg: if clause in kb.clauses: possible = False if possible: possible_actions.append(action) return possible_actions
def h_ignore_preconditions(self, node: Node): """This heuristic estimates the minimum number of actions that must be carried out from the current state in order to satisfy all of the goal conditions by ignoring the preconditions required for an action to be executed. """ # TODO implement (see Russell-Norvig Ed-3 10.2.3 or Russell-Norvig Ed-2 11.2) count = 0 # Similar to goal_test() but modified to estimate the number of actions # required to reach the goal kb = PropKB() kb.tell(decode_state(node.state, self.state_map).pos_sentence()) for clause in self.goal: if clause not in kb.clauses: count += 1 #print("\n\ncount", count) #print("kb clauses" ,kb.clauses) #print("goal", self.goal) return count
def result(self, state: str, action: Action): """ Return the state that results from executing the given action in the given state. The action must be one of self.actions(state). :param state: state entering node :param action: Action applied :return: resulting state after action """ kb = PropKB(decode_state(state, self.state_map).sentence()) # Not sure why action.args should be given here instead # of using it as default. action.act(kb, action.args) # FAIL, kb does not have a method to go back to a FluentState? pos_list = [ clause for clause in kb.clauses if '~' != clause.__repr__()[0] ] neg_list = [ clause for clause in kb.clauses if '~' == clause.__repr__()[0] ] return encode_state(FluentState(pos_list, neg_list), self.state_map)
def actions(self, state: str) -> list: """ Return the actions that can be executed in the given state. :param state: str state represented as T/F string of mapped fluents (state variables) e.g. 'FTTTFF' :return: list of Action objects """ current_states = decode_state(state, self.state_map) available_actions = self.get_actions() possible_actions = [] for action in available_actions: # print("action: {}{}".format(action.name, action.args)) # print("precon_pos: {}".format(action.precond_pos)) if (all(precon_pos in current_states.pos for precon_pos in action.precond_pos)) and \ (all(precon_neg in current_states.neg for precon_neg in action.precond_neg)): possible_actions.append(action) return possible_actions
def h_ignore_preconditions(self, node: Node): """This heuristic estimates the minimum number of actions that must be carried out from the current state in order to satisfy all of the goal conditions by ignoring the preconditions required for an action to be executed. """ # TODO implement (see Russell-Norvig Ed-3 10.2.3 or Russell-Norvig Ed-2 11.2) count = 0 # we need to count number of actions that needed to satisfy each goal condition in the goal state. # If the goal condition is already satisified, no additional action needed. # define a propositional logic and find all positive conditions in node state kb = PropKB() kb.tell(decode_state(node.state, self.state_map).pos_sentence()) # count how many expressions in goal conditions are not in the current node state positive conditions count = len( [clause for clause in self.goal if clause not in kb.clauses]) return count
def actions(self, state: str) -> list: """ Return the actions that can be executed in the given state. :param state: str state represented as T/F string of mapped fluents (state variables) e.g. 'FTTTFF' :return: list of Action objects """ possible_actions = [] decoded_state = decode_state(state, self.state_map) for action in self.actions_list: is_possible = True for clause in action.precond_pos: if clause not in decoded_state.pos: is_possible = False for clause in action.precond_neg: if clause not in decoded_state.neg: is_possible = False if is_possible: possible_actions.append(action) return possible_actions
def result(self, state: str, action: Action): """ Return the state that results from executing the given action in the given state. The action must be one of self.actions(state). :param state: state entering node :param action: Action applied :return: resulting state after action """ new_state = FluentState([], []) current_state = decode_state(state, self.state_map) pos_list = [s for s in current_state.pos if s not in action.effect_rem] pos_list.extend(action.effect_add) neg_list = [s for s in current_state.neg if s not in action.effect_add] neg_list.extend(action.effect_rem) new_state = FluentState(pos_list, neg_list) # print(new_state.pos) # print(new_state.neg) return encode_state(new_state, self.state_map)
def h_ignore_preconditions(self, node: Node): """This heuristic estimates the minimum number of actions that must be carried out from the current state in order to satisfy all of the goal conditions by ignoring the preconditions required for an action to be executed. """ # TODO implement (see Russell-Norvig Ed-3 10.2.3 or Russell-Norvig Ed-2 11.2) # create the knowledge base kb = PropKB() # Add the pos sentence to the knowledge base kb.tell(decode_state(node.state, self.state_map).pos_sentence()) count = 0 # count how many clauses are not yet in the knowledge base and return that total number as the heuristic result for clause in self.goal: if clause not in kb.clauses: count += 1 return count
def actions(self, state: str) -> list: """ Return the actions that can be executed in the given state. :param state: str state represented as T/F string of mapped fluents (state variables) e.g. 'FTTTFF' :return: list of Action objects """ possible_actions = [] fluents = decode_state(state, self.state_map) pos_fluents = fluents.pos neg_fluents = fluents.neg for action in self.actions_list: if set(action.precond_pos).issubset(pos_fluents) and set( action.precond_neg).issubset(neg_fluents): possible_actions.append(action) return possible_actions
def h_ignore_preconditions(self, node: Node): ''' This heuristic estimates the minimum number of actions that must be carried out from the current state in order to satisfy all of the goal conditions by ignoring the preconditions required for an action to be executed. ''' # TODO implement (see Russell-Norvig Ed-3 10.2.3 or Russell-Norvig Ed-2 11.2) count = 0 #print("node.literal = " , node.literal) nodeState = decode_state(node.state, self.state_map) fsPos = nodeState.pos #print("node.state = " , nodeState.pos) #print("self.goal = " , self.goal) goalsPresent = 0 for goal in self.goal: if goal in fsPos: goalsPresent += 1 count = len(self.goal) - goalsPresent
def h_ignore_preconditions(self, node: Node): """This heuristic estimates the minimum number of actions that must be carried out from the current state in order to satisfy all of the goal conditions by ignoring the preconditions required for an action to be executed. """ # TODO implement (see Russell-Norvig Ed-3 10.2.3 or Russell-Norvig Ed-2 11.2) count = 0 cuurent_state = node.state kb = PropKB() kb.tell(decode_state(cuurent_state, self.state_map).pos_sentence()) # Ref: https://discussions.udacity.com/t/understanding-ignore-precondition-heuristic/225906/2 # So what you really want to do is figure out how many of the goal states are not yet satisfied in the current state. # Because the number of unsatisfied goals equals the minimum number of actions you would need to take to satisfy them all. for clause in self.goal: if clause not in kb.clauses: # if it is not satisfied, plus one count += 1 return count
def result(self, state: str, action: Action): """ Return the state that results from executing the given action in the given state. The action must be one of self.actions(state). :param state: state entering node :param action: Action applied :return: resulting state after action """ new_state = FluentState([], []) # Create knowledge base kb = PropKB() # Add the current state to the KB kb.tell(decode_state(state, self.state_map).pos_sentence()) # Change the KB according to action action.act(kb, action.args) # Add those changes to the FluentState for i in kb.clauses: new_state.pos.append(i) # Return the state in string formate (encode) return encode_state(new_state, self.state_map)
def h_ignore_preconditions(self, node: Node): """This heuristic estimates the minimum number of actions that must be carried out from the current state in order to satisfy all of the goal conditions by ignoring the preconditions required for an action to be executed. """ # TODO implement (see Russell-Norvig Ed-3 10.2.3 or Russell-Norvig Ed-2 11.2) count = 0 # create a knowledge base kb = PropKB() # decode the state kb.tell(decode_state(node.state, self.state_map).pos_sentence()) # loop through the goals for clause in self.goal: # if the goal is not present if clause not in kb.clauses: # increment the counter count += 1 # return the count of remaining steps return count
def result(self, state: str, action: Action): """ Return the state that results from executing the given action in the given state. The action must be one of self.actions(state). :param state: state entering node :param action: Action applied :return: resulting state after action """ # TODO implement new_state = FluentState([], []) kb = PropKB() kb.tell(decode_state(state, self.state_map).pos_sentence()) action.check_precond(kb, action.args) action.act(kb, action.args) for clause in kb.clauses: if kb.ask_if_true: new_state.pos.append(clause) else: new_state.neg.append(clause) return encode_state(new_state, self.state_map)
def result(self, state: str, action: Action): """ Return the state that results from executing the given action in the given state. The action must be one of self.actions(state). :param state: state entering node :param action: Action applied :return: resulting state after action """ kb = PropKB() curr_state = decode_state(state, self.state_map) kb.tell(curr_state.pos_sentence()) # If the given action cannot be done in the current state, # then we return the current state. if not action.check_precond(kb, action.args): return state # Do the action with the current knowledge base. action.act(kb, action.args) # Construct the new_state straight from the knowledge base. new_state = "".join(['T' if kb.ask_if_true(s) else 'F' for s in self.state_map]) return new_state
def actions(self, state: str) -> list: """ Return the actions that can be executed in the given state. :param state: str state represented as T/F string of mapped fluents (state variables) e.g. 'FTTTFF' :return: list of Action objects """ possible_actions = [] kb = PropKB() kb.tell(decode_state(state, self.state_map).pos_sentence()) for action in self.actions_list: possible = True for clause in action.precond_pos: if clause not in kb.clauses: possible = False for clause in action.precond_neg: if clause in kb.clauses: possible = False if possible: possible_actions.append(action) return possible_actions
def test_AC_result(self): fs = decode_state(self.p1.result(self.p1.initial, self.act1), self.p1.state_map) self.assertTrue(expr('In(C1, P1)') in fs.pos) self.assertTrue(expr('At(C1, SFO)') in fs.neg)