import_app_module(package, module_name)<EOL>

Imports a module from a given package.

    :param str|unicode package:
    :param str|unicode module_name:


<EOL>settings_locals = get_frame_locals(<NUM_LIT:3>)<EOL>if '<STR_LIT>' not in settings_locals:  <EOL><INDENT>project_package = settings_locals['<STR_LIT>']  <EOL>if not project_package:<EOL><INDENT>project_package = os.path.split(os.path.dirname(settings_locals['<STR_LIT>']))[-<NUM_LIT:1>]<EOL><DEDENT>import_module(project_package, PREFS_MODULE_NAME)<EOL><DEDENT>import_project_modules(PREFS_MODULE_NAME)<EOL>

Imports preferences modules from packages (apps) and project root.


def __init__(<EOL>self, name, default, category=None, field=None, verbose_name=None, help_text='<STR_LIT>', static=True,<EOL>readonly=False):

self.name = name<EOL>self.category = category<EOL>self.default = default<EOL>self.static = static<EOL>self.help_text = help_text<EOL>if static:<EOL><INDENT>readonly = True<EOL><DEDENT>self.readonly = readonly<EOL>if verbose_name is None:<EOL><INDENT>verbose_name = name.replace('<STR_LIT:_>', '<STR_LIT:U+0020>').capitalize()<EOL><DEDENT>self.verbose_name = verbose_name<EOL>if field is None:<EOL><INDENT>self.field = get_field_for_proxy(self)<EOL><DEDENT>else:<EOL><INDENT>self.field = field<EOL>update_field_from_proxy(self.field, self)<EOL><DEDENT>

:param str|unicode name: Preference name.

:param default: Default (initial) value.

:param str|unicode category: Category name the preference belongs to.

:param Field field: Django model field to represent this preference.

:param str|unicode verbose_name: Field verbose name.

:param str|unicode help_text: Field help text.

:param bool static: Leave this preference static (do not store in DB).

:param bool readonly: Make this field read only.


db_prefs = {<EOL>'<STR_LIT>' % (pref['<STR_LIT>'], pref['<STR_LIT:name>']): pref for pref in<EOL>cls.objects.values().order_by('<STR_LIT>', '<STR_LIT:name>')<EOL>}<EOL>new_prefs = []<EOL>for app, prefs in mem_prefs.items():<EOL><INDENT>for pref_name, pref_proxy in prefs.items():<EOL><INDENT>if not pref_proxy.static:  <EOL><INDENT>key = '<STR_LIT>' % (app, pref_name)<EOL>if key in db_prefs:<EOL><INDENT>pref_proxy.db_value = db_prefs[key]['<STR_LIT:text>']<EOL><DEDENT>else:<EOL><INDENT>new_prefs.append(cls(app=app, name=pref_name, text=pref_proxy.default))<EOL><DEDENT><DEDENT><DEDENT><DEDENT>if new_prefs:<EOL><INDENT>try:<EOL><INDENT>cls.objects.bulk_create(new_prefs)<EOL><DEDENT>except IntegrityError:  <EOL><INDENT>pass<EOL><DEDENT><DEDENT>

Initializes preferences entries in DB according to currently discovered prefs.

        :param dict mem_prefs:


Preference.update_prefs(*args, **kwargs)<EOL>Preference.read_prefs(get_prefs())<EOL>

Triggered on dynamic preferences model save.
     Issues DB save and reread.


global __PREFS_REGISTRY<EOL>if __PREFS_REGISTRY is None:<EOL><INDENT>__PREFS_REGISTRY = __PREFS_DEFAULT_REGISTRY<EOL><DEDENT>return __PREFS_REGISTRY<EOL>

Returns a dictionary with all preferences discovered by siteprefs.


if app is None:<EOL><INDENT>with Frame(stepback=<NUM_LIT:1>) as frame:<EOL><INDENT>app = frame.f_globals['<STR_LIT>'].split('<STR_LIT:.>')[<NUM_LIT:0>]<EOL><DEDENT><DEDENT>prefs = get_prefs()<EOL>if app not in prefs:<EOL><INDENT>return {}<EOL><DEDENT>return prefs[app]<EOL>

Returns a dictionary with preferences for a certain app/module.

    :param str|unicode app:

    :rtype: dict


return __MODELS_REGISTRY<EOL>

Returns registered preferences models indexed by application names.

    :rtype: dict


def bind_proxy(values, category=None, field=None, verbose_name=None, help_text='<STR_LIT>', static=True, readonly=False):

addrs = OrderedDict()<EOL>depth = <NUM_LIT:3><EOL>for local_name, locals_dict in traverse_local_prefs(depth):<EOL><INDENT>addrs[id(locals_dict[local_name])] = local_name<EOL><DEDENT>proxies = []<EOL>locals_dict = get_frame_locals(depth)<EOL>for value in values:  <EOL><INDENT>id_val = id(value)<EOL>if id_val in addrs:<EOL><INDENT>local_name = addrs[id_val]<EOL>local_val = locals_dict[local_name]<EOL>if isinstance(local_val, PatchedLocal) and not isinstance(local_val, PrefProxy):<EOL><INDENT>proxy = PrefProxy(<EOL>local_name, value.val,<EOL>category=category,<EOL>field=field,<EOL>verbose_name=verbose_name,<EOL>help_text=help_text,<EOL>static=static,<EOL>readonly=readonly,<EOL>)<EOL>app_name = locals_dict['<STR_LIT>'].split('<STR_LIT:.>')[-<NUM_LIT:2>]  <EOL>prefs = get_prefs()<EOL>if app_name not in prefs:<EOL><INDENT>prefs[app_name] = OrderedDict()<EOL><DEDENT>prefs[app_name][local_name.lower()] = proxy<EOL>locals_dict[local_name] = proxy<EOL>proxies.append(proxy)<EOL><DEDENT><DEDENT><DEDENT>return proxies<EOL>

Binds PrefProxy objects to module variables used by apps as preferences.

    :param list|tuple values: Preference values.

    :param str|unicode category: Category name the preference belongs to.

    :param Field field: Django model field to represent this preference.

    :param str|unicode verbose_name: Field verbose name.

    :param str|unicode help_text: Field help text.

    :param bool static: Leave this preference static (do not store in DB).

    :param bool readonly: Make this field read only.

    :rtype: list


global __MODELS_REGISTRY<EOL>prefs = get_prefs()<EOL>for app_label, prefs_items in prefs.items():<EOL><INDENT>model_class = get_pref_model_class(app_label, prefs_items, get_app_prefs)<EOL>if model_class is not None:<EOL><INDENT>__MODELS_REGISTRY[app_label] = model_class<EOL>admin_site.register(model_class, get_pref_model_admin_class(prefs_items))<EOL><DEDENT><DEDENT>

Registers dynamically created preferences models for Admin interface.

    :param admin.AdminSite admin_site: AdminSite object.


if admin_site is None:<EOL><INDENT>admin_site = admin.site<EOL><DEDENT>if '<STR_LIT>' not in sys.argv[<NUM_LIT:0>] or (len(sys.argv) > <NUM_LIT:1> and sys.argv[<NUM_LIT:1>] in MANAGE_SAFE_COMMANDS):<EOL><INDENT>import_prefs()<EOL>Preference.read_prefs(get_prefs())<EOL>register_admin_models(admin_site)<EOL><DEDENT>

Automatically discovers and registers all preferences available in all apps.

    :param admin.AdminSite admin_site: Custom AdminSite object.


for name, locals_dict in traverse_local_prefs(depth):<EOL><INDENT>locals_dict[name] = PatchedLocal(name, locals_dict[name])<EOL><DEDENT>get_frame_locals(depth)[__PATCHED_LOCALS_SENTINEL] = True<EOL>

Temporarily (see unpatch_locals()) replaces all module variables
    considered preferences with PatchedLocal objects, so that every
    variable has different hash returned by id().


for name, locals_dict in traverse_local_prefs(depth):<EOL><INDENT>if isinstance(locals_dict[name], PatchedLocal):<EOL><INDENT>locals_dict[name] = locals_dict[name].val<EOL><DEDENT><DEDENT>del get_frame_locals(depth)[__PATCHED_LOCALS_SENTINEL]<EOL>

Restores the original values of module variables
    considered preferences if they are still PatchedLocal
    and not PrefProxy.


proxies = []<EOL>modules = sys.modules<EOL>module_name = get_frame_locals(depth)['<STR_LIT>']<EOL>module_real = modules[module_name]<EOL>for name, locals_dict in traverse_local_prefs(depth):<EOL><INDENT>value = locals_dict[name]<EOL>if isinstance(value, PrefProxy):<EOL><INDENT>proxies.append(name)<EOL><DEDENT><DEDENT>new_module = type(module_name, (ModuleType, ModuleProxy), {})(module_name)  <EOL>new_module.bind(module_real, proxies)<EOL>modules[module_name] = new_module<EOL>

Replaces a settings module with a Module proxy to intercept
    an access to settings.

    :param int depth: Frame count to go backward.


swap_settings_module = bool(kwargs.get('<STR_LIT>', True))<EOL>if __PATCHED_LOCALS_SENTINEL not in get_frame_locals(<NUM_LIT:2>):<EOL><INDENT>raise SitePrefsException('<STR_LIT>')<EOL><DEDENT>bind_proxy(args, **kwargs)<EOL>unpatch_locals()<EOL>swap_settings_module and proxy_settings_module()<EOL>

Registers preferences that should be handled by siteprefs.

    Expects preferences as *args.

    Use keyword arguments to batch apply params supported by
    ``PrefProxy`` to all preferences not constructed by ``pref`` and ``pref_group``.

    Batch kwargs:

        :param str|unicode help_text: Field help text.

        :param bool static: Leave this preference static (do not store in DB).

        :param bool readonly: Make this field read only.

    :param bool swap_settings_module: Whether to automatically replace settings module
        with a special ``ProxyModule`` object to access dynamic values of settings
        transparently (so not to bother with calling ``.value`` of ``PrefProxy`` object).


def pref_group(title, prefs, help_text='<STR_LIT>', static=True, readonly=False):

bind_proxy(prefs, title, help_text=help_text, static=static, readonly=readonly)<EOL>for proxy in prefs:  <EOL><INDENT>if isinstance(proxy, PrefProxy):<EOL><INDENT>proxy.category = title<EOL><DEDENT><DEDENT>

Marks preferences group.

    :param str|unicode title: Group title

    :param list|tuple prefs: Preferences to group.

    :param str|unicode help_text: Field help text.

    :param bool static: Leave this preference static (do not store in DB).

    :param bool readonly: Make this field read only.


def pref(preference, field=None, verbose_name=None, help_text='<STR_LIT>', static=True, readonly=False):

Marks a preference.

    :param preference: Preference variable.

    :param Field field: Django model field to represent this preference.

    :param str|unicode verbose_name: Field verbose name.

    :param str|unicode help_text: Field help text.

    :param bool static: Leave this preference static (do not store in DB).

    :param bool readonly: Make this field read only.

    :rtype: PrefProxy|None


self._module = module<EOL>self._prefs = set(prefs)<EOL>

:param ModuleType module:
:param list prefs: Preference names. Just to speed up __getattr__.


frontier.append(Node(problem.initial))<EOL>while frontier:<EOL><INDENT>node = frontier.pop()<EOL>if problem.goal_test(node.state):<EOL><INDENT>return node<EOL><DEDENT>frontier.extend(node.expand(problem))<EOL><DEDENT>return None<EOL>

Search through the successors of a problem to find a goal.
    The argument frontier should be an empty queue.
    Don't worry about repeated paths to a state. [Fig. 3.7]


frontier.append(Node(problem.initial))<EOL>explored = set()<EOL>while frontier:<EOL><INDENT>node = frontier.pop()<EOL>if problem.goal_test(node.state):<EOL><INDENT>return node<EOL><DEDENT>explored.add(node.state)<EOL>frontier.extend(child for child in node.expand(problem)<EOL>if child.state not in explored<EOL>and child not in frontier)<EOL><DEDENT>return None<EOL>

Search through the successors of a problem to find a goal.
    The argument frontier should be an empty queue.
    If two paths reach a state, only use the first one. [Fig. 3.7]


return tree_search(problem, FIFOQueue())<EOL>

Search the shallowest nodes in the search tree first.


return tree_search(problem, Stack())<EOL>

Search the deepest nodes in the search tree first.


return graph_search(problem, Stack())<EOL>


node = Node(problem.initial)<EOL>if problem.goal_test(node.state):<EOL><INDENT>return node<EOL><DEDENT>frontier = FIFOQueue()<EOL>frontier.append(node)<EOL>explored = set()<EOL>while frontier:<EOL><INDENT>node = frontier.pop()<EOL>explored.add(node.state)<EOL>for child in node.expand(problem):<EOL><INDENT>if child.state not in explored and child not in frontier:<EOL><INDENT>if problem.goal_test(child.state):<EOL><INDENT>return child<EOL><DEDENT>frontier.append(child)<EOL><DEDENT><DEDENT><DEDENT>return None<EOL>


f = memoize(f, '<STR_LIT:f>')<EOL>node = Node(problem.initial)<EOL>if problem.goal_test(node.state):<EOL><INDENT>return node<EOL><DEDENT>frontier = PriorityQueue(min, f)<EOL>frontier.append(node)<EOL>explored = set()<EOL>while frontier:<EOL><INDENT>node = frontier.pop()<EOL>if problem.goal_test(node.state):<EOL><INDENT>return node<EOL><DEDENT>explored.add(node.state)<EOL>for child in node.expand(problem):<EOL><INDENT>if child.state not in explored and child not in frontier:<EOL><INDENT>frontier.append(child)<EOL><DEDENT>elif child in frontier:<EOL><INDENT>incumbent = frontier[child]<EOL>if f(child) < f(incumbent):<EOL><INDENT>del frontier[incumbent]<EOL>frontier.append(child)<EOL><DEDENT><DEDENT><DEDENT><DEDENT>return None<EOL>

Search the nodes with the lowest f scores first.
    You specify the function f(node) that you want to minimize; for example,
    if f is a heuristic estimate to the goal, then we have greedy best
    first search; if f is node.depth then we have breadth-first search.
    There is a subtlety: the line "f = memoize(f, 'f')" means that the f
    values will be cached on the nodes as they are computed. So after doing
    a best first search you can examine the f values of the path returned.


return best_first_graph_search(problem, lambda node: node.path_cost)<EOL>


def recursive_dls(node, problem, limit):<EOL><INDENT>if problem.goal_test(node.state):<EOL><INDENT>return node<EOL><DEDENT>elif node.depth == limit:<EOL><INDENT>return '<STR_LIT>'<EOL><DEDENT>else:<EOL><INDENT>cutoff_occurred = False<EOL>for child in node.expand(problem):<EOL><INDENT>result = recursive_dls(child, problem, limit)<EOL>if result == '<STR_LIT>':<EOL><INDENT>cutoff_occurred = True<EOL><DEDENT>elif result is not None:<EOL><INDENT>return result<EOL><DEDENT><DEDENT>return if_(cutoff_occurred, '<STR_LIT>', None)<EOL><DEDENT><DEDENT>return recursive_dls(Node(problem.initial), problem, limit)<EOL>


for depth in range(sys.maxsize):<EOL><INDENT>result = depth_limited_search(problem, depth)<EOL>if result != '<STR_LIT>':<EOL><INDENT>return result<EOL><DEDENT><DEDENT>


h = memoize(h or problem.h, '<STR_LIT:h>')<EOL>return best_first_graph_search(problem, lambda n: n.path_cost + h(n))<EOL>

A* search is best-first graph search with f(n) = g(n)+h(n).
    You need to specify the h function when you call astar_search, or
    else in your Problem subclass.


h = memoize(h or problem.h, '<STR_LIT:h>')<EOL>def RBFS(problem, node, flimit):<EOL><INDENT>if problem.goal_test(node.state):<EOL><INDENT>return node, <NUM_LIT:0>   <EOL><DEDENT>successors = node.expand(problem)<EOL>if len(successors) == <NUM_LIT:0>:<EOL><INDENT>return None, infinity<EOL><DEDENT>for s in successors:<EOL><INDENT>s.f = max(s.path_cost + h(s), node.f)<EOL><DEDENT>while True:<EOL><INDENT>successors.sort(lambda x,y: cmp(x.f, y.f)) <EOL>best = successors[<NUM_LIT:0>]<EOL>if best.f > flimit:<EOL><INDENT>return None, best.f<EOL><DEDENT>if len(successors) > <NUM_LIT:1>:<EOL><INDENT>alternative = successors[<NUM_LIT:1>].f<EOL><DEDENT>else:<EOL><INDENT>alternative = infinity<EOL><DEDENT>result, best.f = RBFS(problem, best, min(flimit, alternative))<EOL>if result is not None:<EOL><INDENT>return result, best.f<EOL><DEDENT><DEDENT><DEDENT>node = Node(problem.initial)<EOL>node.f = h(node)<EOL>result, bestf = RBFS(problem, node, infinity)<EOL>return result<EOL>


current = Node(problem.initial)<EOL>while True:<EOL><INDENT>neighbors = current.expand(problem)<EOL>if not neighbors:<EOL><INDENT>break<EOL><DEDENT>neighbor = argmax_random_tie(neighbors,<EOL>lambda node: problem.value(node.state))<EOL>if problem.value(neighbor.state) <= problem.value(current.state):<EOL><INDENT>break<EOL><DEDENT>current = neighbor<EOL><DEDENT>return current.state<EOL>

From the initial node, keep choosing the neighbor with highest value,
    stopping when no neighbor is better. [Fig. 4.2]


def exp_schedule(k=<NUM_LIT:20>, lam=<NUM_LIT>, limit=<NUM_LIT:100>):

return lambda t: if_(t < limit, k * math.exp(-lam * t), <NUM_LIT:0>)<EOL>

One possible schedule function for simulated annealing


current = Node(problem.initial)<EOL>for t in range(sys.maxsize):<EOL><INDENT>T = schedule(t)<EOL>if T == <NUM_LIT:0>:<EOL><INDENT>return current<EOL><DEDENT>neighbors = current.expand(problem)<EOL>if not neighbors:<EOL><INDENT>return current<EOL><DEDENT>next = random.choice(neighbors)<EOL>delta_e = problem.value(next.state) - problem.value(current.state)<EOL>if delta_e > <NUM_LIT:0> or probability(math.exp(delta_e/T)):<EOL><INDENT>current = next<EOL><DEDENT><DEDENT>


unimplemented()<EOL>


def genetic_search(problem, fitness_fn, ngen=<NUM_LIT:1000>, pmut=<NUM_LIT:0.1>, n=<NUM_LIT:20>):

s = problem.initial_state<EOL>states = [problem.result(s, a) for a in problem.actions(s)]<EOL>random.shuffle(states)<EOL>return genetic_algorithm(states[:n], problem.value, ngen, pmut)<EOL>

Call genetic_algorithm on the appropriate parts of a problem.
    This requires the problem to have states that can mate and mutate,
    plus a value method that scores states.


def genetic_algorithm(population, fitness_fn, ngen=<NUM_LIT:1000>, pmut=<NUM_LIT:0.1>):

for i in range(ngen):<EOL><INDENT>new_population = []<EOL>for i in len(population):<EOL><INDENT>fitnesses = list(map(fitness_fn, population))<EOL>p1, p2 = weighted_sample_with_replacement(population, fitnesses, <NUM_LIT:2>)<EOL>child = p1.mate(p2)<EOL>if random.uniform(<NUM_LIT:0>, <NUM_LIT:1>) < pmut:<EOL><INDENT>child.mutate()<EOL><DEDENT>new_population.append(child)<EOL><DEDENT>population = new_population<EOL><DEDENT>return argmax(population, fitness_fn)<EOL>


return Graph(dict=dict, directed=False)<EOL>

Build a Graph where every edge (including future ones) goes both ways.


def RandomGraph(nodes=list(range(<NUM_LIT:10>)), min_links=<NUM_LIT:2>, width=<NUM_LIT>, height=<NUM_LIT>,<EOL>curvature=lambda: random.uniform(<NUM_LIT>, <NUM_LIT>)):

g = UndirectedGraph()<EOL>g.locations = {}<EOL>for node in nodes:<EOL><INDENT>g.locations[node] = (random.randrange(width), random.randrange(height))<EOL><DEDENT>for i in range(min_links):<EOL><INDENT>for node in nodes:<EOL><INDENT>if len(g.get(node)) < min_links:<EOL><INDENT>here = g.locations[node]<EOL>def distance_to_node(n):<EOL><INDENT>if n is node or g.get(node,n): return infinity<EOL>return distance(g.locations[n], here)<EOL><DEDENT>neighbor = argmin(nodes, distance_to_node)<EOL>d = distance(g.locations[neighbor], here) * curvature()<EOL>g.connect(node, neighbor, int(d))<EOL><DEDENT><DEDENT><DEDENT>return g<EOL>

Construct a random graph, with the specified nodes, and random links.
    The nodes are laid out randomly on a (width x height) rectangle.
    Then each node is connected to the min_links nearest neighbors.
    Because inverse links are added, some nodes will have more connections.
    The distance between nodes is the hypotenuse times curvature(),
    where curvature() defaults to a random number between 1.1 and 1.5.


cubes = [cubes16[i % <NUM_LIT:16>] for i in range(n*n)]<EOL>random.shuffle(cubes)<EOL>return list(map(random.choice, cubes))<EOL>

Return a random Boggle board of size n x n.
    We represent a board as a linear list of letters.


n2 = len(board); n = exact_sqrt(n2)<EOL>for i in range(n2):<EOL><INDENT>if i % n == <NUM_LIT:0> and i > <NUM_LIT:0>: print()<EOL>if board[i] == '<STR_LIT>': print('<STR_LIT>', end='<STR_LIT:U+0020>')<EOL>else: print(str(board[i]) + '<STR_LIT:U+0020>', end='<STR_LIT:U+0020>')<EOL><DEDENT>print()<EOL>


if cache.get(n2):<EOL><INDENT>return cache.get(n2)<EOL><DEDENT>n = exact_sqrt(n2)<EOL>neighbors = [None] * n2<EOL>for i in range(n2):<EOL><INDENT>neighbors[i] = []<EOL>on_top = i < n<EOL>on_bottom = i >= n2 - n<EOL>on_left = i % n == <NUM_LIT:0><EOL>on_right = (i+<NUM_LIT:1>) % n == <NUM_LIT:0><EOL>if not on_top:<EOL><INDENT>neighbors[i].append(i - n)<EOL>if not on_left:  neighbors[i].append(i - n - <NUM_LIT:1>)<EOL>if not on_right: neighbors[i].append(i - n + <NUM_LIT:1>)<EOL><DEDENT>if not on_bottom:<EOL><INDENT>neighbors[i].append(i + n)<EOL>if not on_left:  neighbors[i].append(i + n - <NUM_LIT:1>)<EOL>if not on_right: neighbors[i].append(i + n + <NUM_LIT:1>)<EOL><DEDENT>if not on_left: neighbors[i].append(i - <NUM_LIT:1>)<EOL>if not on_right: neighbors[i].append(i + <NUM_LIT:1>)<EOL><DEDENT>cache[n2] = neighbors<EOL>return neighbors<EOL>

Return a list of lists, where the i-th element is the list of indexes
    for the neighbors of square i.


n = int(math.sqrt(n2))<EOL>assert n * n == n2<EOL>return n<EOL>

If n2 is a perfect square, return its square root, else raise error.


def boggle_hill_climbing(board=None, ntimes=<NUM_LIT:100>, verbose=True):

finder = BoggleFinder()<EOL>if board is None:<EOL><INDENT>board = random_boggle()<EOL><DEDENT>best = len(finder.set_board(board))<EOL>for _ in range(ntimes):<EOL><INDENT>i, oldc = mutate_boggle(board)<EOL>new = len(finder.set_board(board))<EOL>if new > best:<EOL><INDENT>best = new<EOL>if verbose: print(best, _, board)<EOL><DEDENT>else:<EOL><INDENT>board[i] = oldc <EOL><DEDENT><DEDENT>if verbose:<EOL><INDENT>print_boggle(board)<EOL><DEDENT>return board, best<EOL>

Solve inverse Boggle by hill-climbing: find a high-scoring board by
    starting with a random one and changing it.


compare_searchers(problems=[GraphProblem('<STR_LIT:A>', '<STR_LIT:B>', romania),<EOL>GraphProblem('<STR_LIT:O>', '<STR_LIT:N>', romania),<EOL>GraphProblem('<STR_LIT>', '<STR_LIT>', australia)],<EOL>header=['<STR_LIT>', '<STR_LIT>', '<STR_LIT>', '<STR_LIT>'])<EOL>


self.initial = initial; self.goal = goal<EOL>

The constructor specifies the initial state, and possibly a goal
        state, if there is a unique goal.  Your subclass's constructor can add
        other arguments.


abstract<EOL>

Return the actions that can be executed in the given
        state. The result would typically be a list, but if there are
        many actions, consider yielding them one at a time in an
        iterator, rather than building them all at once.


abstract<EOL>

Return the state that results from executing the given
        action in the given state. The action must be one of
        self.actions(state).


def path_cost(self, c, state1, action, state2):

return c + <NUM_LIT:1><EOL>

Return the cost of a solution path that arrives at state2 from
        state1 via action, assuming cost c to get up to state1. If the problem
        is such that the path doesn't matter, this function will only look at
        state2.  If the path does matter, it will consider c and maybe state1
        and action. The default method costs 1 for every step in the path.


abstract<EOL>

For optimization problems, each state has a value.  Hill-climbing
        and related algorithms try to maximize this value.


def __init__(self, state, parent=None, action=None, path_cost=<NUM_LIT:0>):

<EOL>update(self, state=state, parent=parent, action=action,<EOL>path_cost=path_cost, depth=<NUM_LIT:0>)<EOL>if parent:<EOL><INDENT>self.depth = parent.depth + <NUM_LIT:1><EOL><DEDENT>

Create a search tree Node, derived from a parent by an action.


return [self.child_node(problem, action)<EOL>for action in problem.actions(self.state)]<EOL>

List the nodes reachable in one step from this node.


next = problem.result(self.state, action)<EOL>return Node(next, self, action,<EOL>problem.path_cost(self.path_cost, self.state, action, next))<EOL>


return [node.action for node in self.path()[<NUM_LIT:1>:]]<EOL>

Return the sequence of actions to go from the root to this node.


node, path_back = self, []<EOL>while node:<EOL><INDENT>path_back.append(node)<EOL>node = node.parent<EOL><DEDENT>return list(reversed(path_back))<EOL>

Return a list of nodes forming the path from the root to this node.


c = random.randrange(len(self.genes))<EOL>return self.__class__(self.genes[:c] + other.genes[c:])<EOL>

Return a new individual crossing self and other.


abstract<EOL>


for a in list(self.dict.keys()):<EOL><INDENT>for (b, distance) in list(self.dict[a].items()):<EOL><INDENT>self.connect1(b, a, distance)<EOL><DEDENT><DEDENT>

Make a digraph into an undirected graph by adding symmetric edges.


def connect(self, A, B, distance=<NUM_LIT:1>):

self.connect1(A, B, distance)<EOL>if not self.directed: self.connect1(B, A, distance)<EOL>

Add a link from A and B of given distance, and also add the inverse
        link if the graph is undirected.


self.dict.setdefault(A,{})[B] = distance<EOL>

Add a link from A to B of given distance, in one direction only.


links = self.dict.setdefault(a, {})<EOL>if b is None: return links<EOL>else: return links.get(b)<EOL>

Return a link distance or a dict of {node: distance} entries.
        .get(a,b) returns the distance or None;
        .get(a) returns a dict of {node: distance} entries, possibly {}.


return list(self.dict.keys())<EOL>


return list(self.graph.get(A).keys())<EOL>

The actions at a graph node are just its neighbors.


return action<EOL>

The result of going to a neighbor is just that neighbor.


locs = getattr(self.graph, '<STR_LIT>', None)<EOL>if locs:<EOL><INDENT>return int(distance(locs[node.state], locs[self.goal]))<EOL><DEDENT>else:<EOL><INDENT>return infinity<EOL><DEDENT>

h function is straight-line distance from a node's state to goal.


if state[-<NUM_LIT:1>] is not None:<EOL><INDENT>return []  <EOL><DEDENT>else:<EOL><INDENT>col = state.index(None)<EOL>return [row for row in range(self.N)<EOL>if not self.conflicted(state, row, col)]<EOL><DEDENT>

In the leftmost empty column, try all non-conflicting rows.


col = state.index(None)<EOL>new = state[:]<EOL>new[col] = row<EOL>return new<EOL>


return any(self.conflict(row, col, state[c], c)<EOL>for c in range(col))<EOL>

Would placing a queen at (row, col) conflict with anything?


def conflict(self, row1, col1, row2, col2):

return (row1 == row2 <EOL>or col1 == col2 <EOL>or row1-col1 == row2-col2  <EOL>or row1+col1 == row2+col2)<EOL>

Would putting two queens in (row1, col1) and (row2, col2) conflict?


def lookup(self, prefix, lo=<NUM_LIT:0>, hi=None):

words = self.words<EOL>if hi is None: hi = len(words)<EOL>i = bisect.bisect_left(words, prefix, lo, hi)<EOL>if i < len(words) and words[i].startswith(prefix):<EOL><INDENT>return i, (words[i] == prefix)<EOL><DEDENT>else:<EOL><INDENT>return None, False<EOL><DEDENT>

See if prefix is in dictionary, as a full word or as a prefix.
        Return two values: the first is the lowest i such that
        words[i].startswith(prefix), or is None; the second is
        True iff prefix itself is in the Wordlist.


if board is None:<EOL><INDENT>board = random_boggle()<EOL><DEDENT>self.board = board<EOL>self.neighbors = boggle_neighbors(len(board))<EOL>self.found = {}<EOL>for i in range(len(board)):<EOL><INDENT>lo, hi = self.wordlist.bounds[board[i]]<EOL>self.find(lo, hi, i, [], '<STR_LIT>')<EOL><DEDENT>return self<EOL>

Set the board, and find all the words in it.


def find(self, lo, hi, i, visited, prefix):

if i in visited:<EOL><INDENT>return<EOL><DEDENT>wordpos, is_word = self.wordlist.lookup(prefix, lo, hi)<EOL>if wordpos is not None:<EOL><INDENT>if is_word:<EOL><INDENT>self.found[prefix] = True<EOL><DEDENT>visited.append(i)<EOL>c = self.board[i]<EOL>if c == '<STR_LIT>': c = '<STR_LIT>'<EOL>prefix += c<EOL>for j in self.neighbors[i]:<EOL><INDENT>self.find(wordpos, hi, j, visited, prefix)<EOL><DEDENT>visited.pop()<EOL><DEDENT>

Looking in square i, find the words that continue the prefix,
        considering the entries in self.wordlist.words[lo:hi], and not
        revisiting the squares in visited.


return list(self.found.keys())<EOL>


return sum([self.scores[len(w)] for w in self.words()])<EOL>

The total score for the words found, according to the rules.


return len(self.found)<EOL>


old_program = agent.program<EOL>def new_program(percept):<EOL><INDENT>action = old_program(percept)<EOL>print('<STR_LIT>' % (agent, percept, action))<EOL>return action<EOL><DEDENT>agent.program = new_program<EOL>return agent<EOL>

Wrap the agent's program to print its input and output. This will let
    you see what the agent is doing in the environment.


percepts = []<EOL>def program(percept):<EOL><INDENT>percepts.append(percept)<EOL>action = table.get(tuple(percepts))<EOL>return action<EOL><DEDENT>return program<EOL>

This agent selects an action based on the percept sequence.
    It is practical only for tiny domains.
    To customize it, provide as table a dictionary of all
    {percept_sequence:action} pairs. [Fig. 2.7]


return lambda percept: random.choice(actions)<EOL>

An agent that chooses an action at random, ignoring all percepts.


def program(percept):<EOL><INDENT>state = interpret_input(percept)<EOL>rule = rule_match(state, rules)<EOL>action = rule.action<EOL>return action<EOL><DEDENT>return program<EOL>

This agent takes action based solely on the percept. [Fig. 2.10]


def program(percept):<EOL><INDENT>program.state = update_state(program.state, program.action, percept)<EOL>rule = rule_match(program.state, rules)<EOL>action = rule.action<EOL>return action<EOL><DEDENT>program.state = program.action = None<EOL>return program<EOL>

This agent takes action based on the percept and state. [Fig. 2.12]


for rule in rules:<EOL><INDENT>if rule.matches(state):<EOL><INDENT>return rule<EOL><DEDENT><DEDENT>


return Agent(RandomAgentProgram(['<STR_LIT>', '<STR_LIT>', '<STR_LIT>', '<STR_LIT>']))<EOL>

Randomly choose one of the actions from the vacuum environment.


table = {((loc_A, '<STR_LIT>'),): '<STR_LIT>',<EOL>((loc_A, '<STR_LIT>'),): '<STR_LIT>',<EOL>((loc_B, '<STR_LIT>'),): '<STR_LIT>',<EOL>((loc_B, '<STR_LIT>'),): '<STR_LIT>',<EOL>((loc_A, '<STR_LIT>'), (loc_A, '<STR_LIT>')): '<STR_LIT>',<EOL>((loc_A, '<STR_LIT>'), (loc_A, '<STR_LIT>')): '<STR_LIT>',<EOL>((loc_A, '<STR_LIT>'), (loc_A, '<STR_LIT>'), (loc_A, '<STR_LIT>')): '<STR_LIT>',<EOL>((loc_A, '<STR_LIT>'), (loc_A, '<STR_LIT>'), (loc_A, '<STR_LIT>')): '<STR_LIT>',<EOL>}<EOL>return Agent(TableDrivenAgentProgram(table))<EOL>


def program(xxx_todo_changeme):<EOL><INDENT>(location, status) = xxx_todo_changeme<EOL>if status == '<STR_LIT>': return '<STR_LIT>'<EOL>elif location == loc_A: return '<STR_LIT>'<EOL>elif location == loc_B: return '<STR_LIT>'<EOL><DEDENT>return Agent(program)<EOL>

A reflex agent for the two-state vacuum environment. [Fig. 2.8]


model = {loc_A: None, loc_B: None}<EOL>def program(xxx_todo_changeme1):<EOL><INDENT>"<STR_LIT>"<EOL>(location, status) = xxx_todo_changeme1<EOL>model[location] = status <EOL>if model[loc_A] == model[loc_B] == '<STR_LIT>': return '<STR_LIT>'<EOL>elif status == '<STR_LIT>': return '<STR_LIT>'<EOL>elif location == loc_A: return '<STR_LIT>'<EOL>elif location == loc_B: return '<STR_LIT>'<EOL><DEDENT>return Agent(program)<EOL>

An agent that keeps track of what locations are clean or dirty.


def compare_agents(EnvFactory, AgentFactories, n=<NUM_LIT:10>, steps=<NUM_LIT:1000>):

envs = [EnvFactory() for i in range(n)]<EOL>return [(A, test_agent(A, steps, copy.deepcopy(envs)))<EOL>for A in AgentFactories]<EOL>

See how well each of several agents do in n instances of an environment.
    Pass in a factory (constructor) for environments, and several for agents.
    Create n instances of the environment, and run each agent in copies of
    each one for steps. Return a list of (agent, average-score) tuples.


return hasattr(self, '<STR_LIT>') and self.alive<EOL>

Things that are 'alive' should return true.


Display the agent's internal state.  Subclasses should override.


def display(self, canvas, x, y, width, height):<EOL>

pass<EOL>

Display an image of this Thing on the canvas.


return False<EOL>

Returns True if this agent can grab this thing.
        Override for appropriate subclasses of Agent and Thing.


abstract<EOL>

Return the percept that the agent sees at this point. (Implement this.)


def execute_action(self, agent, action):

abstract<EOL>

Change the world to reflect this action. (Implement this.)


return None<EOL>

Default location to place a new thing with unspecified location.


pass<EOL>

If there is spontaneous change in the world, override this.


return not any(agent.is_alive() for agent in self.agents)<EOL>

By default, we're done when we can't find a live agent.


if not self.is_done():<EOL><INDENT>actions = [agent.program(self.percept(agent))<EOL>for agent in self.agents]<EOL>for (agent, action) in zip(self.agents, actions):<EOL><INDENT>self.execute_action(agent, action)<EOL><DEDENT>self.exogenous_change()<EOL><DEDENT>

Run the environment for one time step. If the
        actions and exogenous changes are independent, this method will
        do.  If there are interactions between them, you'll need to
        override this method.


for step in range(steps):<EOL><INDENT>if self.is_done(): return<EOL>self.step()<EOL><DEDENT>

Run the Environment for given number of time steps.


def list_things_at(self, location, tclass=Thing):

return [thing for thing in self.things<EOL>if thing.location == location and isinstance(thing, tclass)]<EOL>

Return all things exactly at a given location.


def some_things_at(self, location, tclass=Thing):

return self.list_things_at(location, tclass) != []<EOL>

Return true if at least one of the things at location
        is an instance of class tclass (or a subclass).


def add_thing(self, thing, location=None):

if not isinstance(thing, Thing):<EOL><INDENT>thing = Agent(thing)<EOL><DEDENT>assert thing not in self.things, "<STR_LIT>"<EOL>thing.location = location or self.default_location(thing)<EOL>self.things.append(thing)<EOL>if isinstance(thing, Agent):<EOL><INDENT>thing.performance = <NUM_LIT:0><EOL>self.agents.append(thing)<EOL><DEDENT>

Add a thing to the environment, setting its location. For
        convenience, if thing is an agent program we make a new agent
        for it. (Shouldn't need to override this.


try:<EOL><INDENT>self.things.remove(thing)<EOL><DEDENT>except ValueError as e:<EOL><INDENT>print(e)<EOL>print("<STR_LIT>")<EOL>print("<STR_LIT>" % (thing, thing.location))<EOL>print("<STR_LIT>" % [(thing, thing.location)<EOL>for thing in self.things])<EOL><DEDENT>if thing in self.agents:<EOL><INDENT>self.agents.remove(thing)<EOL><DEDENT>


def things_near(self, location, radius=None):

if radius is None: radius = self.perceptible_distance<EOL>radius2 = radius * radius<EOL>return [thing for thing in self.things<EOL>if distance2(location, thing.location) <= radius2]<EOL>

Return all things within radius of location.


return [self.thing_percept(thing, agent)<EOL>for thing in self.things_near(agent.location)]<EOL>

By default, agent perceives things within a default radius.


return thing.__class__.__name__<EOL>


thing.bump = self.some_things_at(destination, Obstacle)<EOL>if not thing.bump:<EOL><INDENT>thing.location = destination<EOL>for o in self.observers:<EOL><INDENT>o.thing_moved(thing)<EOL><DEDENT><DEDENT>


for x in range(self.width):<EOL><INDENT>self.add_thing(Wall(), (x, <NUM_LIT:0>))<EOL>self.add_thing(Wall(), (x, self.height-<NUM_LIT:1>))<EOL><DEDENT>for y in range(self.height):<EOL><INDENT>self.add_thing(Wall(), (<NUM_LIT:0>, y))<EOL>self.add_thing(Wall(), (self.width-<NUM_LIT:1>, y))<EOL><DEDENT>

Put walls around the entire perimeter of the grid.


self.observers.append(observer)<EOL>

Adds an observer to the list of observers.
        An observer is typically an EnvGUI.

        Each observer is notified of changes in move_to and add_thing,
        by calling the observer's methods thing_moved(thing)
        and thing_added(thing, loc).


return turn_heading(heading, inc)<EOL>

Return the heading to the left (inc=+1) or right (inc=-1) of heading.


status = if_(self.some_things_at(agent.location, Dirt),<EOL>'<STR_LIT>', '<STR_LIT>')<EOL>bump = if_(agent.bump, '<STR_LIT>', '<STR_LIT:None>')<EOL>return (status, bump)<EOL>

The percept is a tuple of ('Dirty' or 'Clean', 'Bump' or 'None').
        Unlike the TrivialVacuumEnvironment, location is NOT perceived.


return (agent.location, self.status[agent.location])<EOL>

Returns the agent's location, and the location status (Dirty/Clean).


if action == '<STR_LIT>':<EOL><INDENT>agent.location = loc_B<EOL>agent.performance -= <NUM_LIT:1><EOL><DEDENT>elif action == '<STR_LIT>':<EOL><INDENT>agent.location = loc_A<EOL>agent.performance -= <NUM_LIT:1><EOL><DEDENT>elif action == '<STR_LIT>':<EOL><INDENT>if self.status[agent.location] == '<STR_LIT>':<EOL><INDENT>agent.performance += <NUM_LIT:10><EOL><DEDENT>self.status[agent.location] = '<STR_LIT>'<EOL><DEDENT>

Change agent's location and/or location's status; track performance.
        Score 10 for each dirt cleaned; -1 for each move.


return random.choice([loc_A, loc_B])<EOL>

Agents start in either location at random.


<EOL>n = len(text)<EOL>words = ['<STR_LIT>'] + list(text)<EOL>best = [<NUM_LIT:1.0>] + [<NUM_LIT:0.0>] * n<EOL>for i in range(n+<NUM_LIT:1>):<EOL><INDENT>for j in range(<NUM_LIT:0>, i):<EOL><INDENT>w = text[j:i]<EOL>if P[w] * best[i - len(w)] >= best[i]:<EOL><INDENT>best[i] = P[w] * best[i - len(w)]<EOL>words[i] = w<EOL><DEDENT><DEDENT><DEDENT>sequence = []; i = len(words)-<NUM_LIT:1><EOL>while i > <NUM_LIT:0>:<EOL><INDENT>sequence[<NUM_LIT:0>:<NUM_LIT:0>] = [words[i]]<EOL>i = i - len(words[i])<EOL><DEDENT>return sequence, best[-<NUM_LIT:1>]<EOL>

Find the best segmentation of the string of characters, given the
    UnigramTextModel P.


return reg.findall(text.lower())<EOL>

Return a list of the words in text, ignoring punctuation and
    converting everything to lowercase (to canonicalize).
    >>> words("``EGAD!'' Edgar cried.")
    ['egad', 'edgar', 'cried']


return '<STR_LIT:U+0020>'.join(words(text))<EOL>

Return a canonical text: only lowercase letters and blanks.
    >>> canonicalize("``EGAD!'' Edgar cried.")
    'egad edgar cried'


return encode(plaintext, alphabet[n:] + alphabet[:n])<EOL>

Encode text with a shift cipher that moves each letter up by n letters.
    >>> shift_encode('abc z', 1)
    'bcd a'


return shift_encode(plaintext, <NUM_LIT>)<EOL>

Encode text by rotating letters by 13 spaces in the alphabet.
    >>> rot13('hello')
    'uryyb'
    >>> rot13(rot13('hello'))
    'hello'


from string import maketrans<EOL>trans = maketrans(alphabet + alphabet.upper(), code + code.upper())<EOL>return plaintext.translate(trans)<EOL>

Encodes text, using a code which is a permutation of the alphabet.


return [text[i:i+<NUM_LIT:2>] for i in range(len(text) - <NUM_LIT:1>)]<EOL>

Return a list of pairs in text (a sequence of letters or words).
    >>> bigrams('this')
    ['th', 'hi', 'is']
    >>> bigrams(['this', 'is', 'a', 'test'])
    [['this', 'is'], ['is', 'a'], ['a', 'test']]


return [shift_encode(text, n) for n in range(len(alphabet))]<EOL>

Return a list of all 26 possible encodings of text by a shift cipher.


return '<STR_LIT:U+0020>'.join([self.sample() for i in range(n)])<EOL>

Return a string of n words, random according to the model.


CountingProbDist.add(self, ngram)<EOL>self.cond_prob[ngram[:-<NUM_LIT:1>]].add(ngram[-<NUM_LIT:1>])<EOL>

Count 1 for P[(w1, ..., wn)] and for P(wn | (w1, ..., wn-1)


n = self.n<EOL>words = ['<STR_LIT>',] * (n-<NUM_LIT:1>) + words<EOL>for i in range(len(words)-n):<EOL><INDENT>self.add(tuple(words[i:i+n]))<EOL><DEDENT>

Add each of the tuple words[i:i+n], using a sliding window.
        Prefix some copies of the empty word, '', to make the start work.


n = self.n<EOL>nminus1gram = ('<STR_LIT>',) * (n-<NUM_LIT:1>)<EOL>output = []<EOL>for i in range(nwords):<EOL><INDENT>if nminus1gram not in self.cond_prob:<EOL><INDENT>nminus1gram = ('<STR_LIT>',) * (n-<NUM_LIT:1>) <EOL><DEDENT>wn = self.cond_prob[nminus1gram].sample()<EOL>output.append(wn)<EOL>nminus1gram = nminus1gram[<NUM_LIT:1>:] + (wn,)<EOL><DEDENT>return '<STR_LIT:U+0020>'.join(output)<EOL>

Build up a random sample of text nwords words long, using
        the conditional probability given the n-1 preceding words.


<EOL>update(self, index=DefaultDict(DefaultDict(<NUM_LIT:0>)),<EOL>stopwords=set(words(stopwords)), documents=[])<EOL>

Create an IR System. Optionally specify stopwords.


for filename in filenames:<EOL><INDENT>self.index_document(open(filename).read(), filename)<EOL><DEDENT>


<EOL>title = text[:text.index('<STR_LIT:\n>')].strip()<EOL>docwords = words(text)<EOL>docid = len(self.documents)<EOL>self.documents.append(Document(title, url, len(docwords)))<EOL>for word in docwords:<EOL><INDENT>if word not in self.stopwords:<EOL><INDENT>self.index[word][docid] += <NUM_LIT:1><EOL><DEDENT><DEDENT>


def query(self, query_text, n=<NUM_LIT:10>):

if query_text.startswith("<STR_LIT>"):<EOL><INDENT>doctext = os.popen(query_text[len("<STR_LIT>"):], '<STR_LIT:r>').read()<EOL>self.index_document(doctext, query_text)<EOL>return []<EOL><DEDENT>qwords = [w for w in words(query_text) if w not in self.stopwords]<EOL>shortest = argmin(qwords, lambda w: len(self.index[w]))<EOL>docs = self.index[shortest]<EOL>results = [(sum([self.score(w, d) for w in qwords]), d) for d in docs]<EOL>results.sort(); results.reverse()<EOL>return results[:n]<EOL>

Return a list of n (score, docid) pairs for the best matches.
        Also handle the special syntax for 'learn: command'.


<EOL>return (math.log(<NUM_LIT:1> + self.index[word][docid])<EOL>/ math.log(<NUM_LIT:1> + self.documents[docid].nwords))<EOL>

Compute a score for this word on this docid.


for (score, d) in results:<EOL><INDENT>doc = self.documents[d]<EOL>print ("<STR_LIT>"<EOL>% (<NUM_LIT:100> * score, doc.url, doc.title[:<NUM_LIT>].expandtabs()))<EOL><DEDENT>


def present_results(self, query_text, n=<NUM_LIT:10>):

self.present(self.query(query_text, n))<EOL>

Get results for the query and present them.


s = <NUM_LIT:1.0><EOL>for bi in bigrams(plaintext):<EOL><INDENT>s = s * self.P2[bi]<EOL><DEDENT>return s<EOL>

Return a score for text based on how common letters pairs are.


return argmax(all_shifts(ciphertext), self.score)<EOL>

Return the shift decoding of text with the best score.


self.ciphertext = ciphertext<EOL>problem = PermutationDecoderProblem(decoder=self)<EOL>return search.best_first_tree_search(<EOL>problem, lambda node: self.score(node.state))<EOL>

Search for a decoding of the ciphertext.


text = permutation_decode(self.ciphertext, code)<EOL>logP = (sum([log(self.Pwords[word]) for word in words(text)]) +<EOL>sum([log(self.P1[c]) for c in text]) +<EOL>sum([log(self.P2[b]) for b in bigrams(text)]))<EOL>return exp(logP)<EOL>

Score is product of word scores, unigram scores, and bigram scores.
        This can get very small, so we use logs and exp.


U1 = dict([(s, <NUM_LIT:0>) for s in mdp.states])<EOL>R, T, gamma = mdp.R, mdp.T, mdp.gamma<EOL>while True:<EOL><INDENT>U = U1.copy()<EOL>delta = <NUM_LIT:0><EOL>for s in mdp.states:<EOL><INDENT>U1[s] = R(s) + gamma * max([sum([p * U[s1] for (p, s1) in T(s, a)])<EOL>for a in mdp.actions(s)])<EOL>delta = max(delta, abs(U1[s] - U[s]))<EOL><DEDENT>if delta < epsilon * (<NUM_LIT:1> - gamma) / gamma:<EOL><INDENT>return U<EOL><DEDENT><DEDENT>

Solving an MDP by value iteration. [Fig. 17.4]


pi = {}<EOL>for s in mdp.states:<EOL><INDENT>pi[s] = argmax(mdp.actions(s), lambda a:expected_utility(a, s, U, mdp))<EOL><DEDENT>return pi<EOL>

Given an MDP and a utility function U, determine the best policy,
    as a mapping from state to action. (Equation 17.4)


return sum([p * U[s1] for (p, s1) in mdp.T(s, a)])<EOL>

The expected utility of doing a in state s, according to the MDP and U.


U = dict([(s, <NUM_LIT:0>) for s in mdp.states])<EOL>pi = dict([(s, random.choice(mdp.actions(s))) for s in mdp.states])<EOL>while True:<EOL><INDENT>U = policy_evaluation(pi, U, mdp)<EOL>unchanged = True<EOL>for s in mdp.states:<EOL><INDENT>a = argmax(mdp.actions(s), lambda a: expected_utility(a,s,U,mdp))<EOL>if a != pi[s]:<EOL><INDENT>pi[s] = a<EOL>unchanged = False<EOL><DEDENT><DEDENT>if unchanged:<EOL><INDENT>return pi<EOL><DEDENT><DEDENT>

Solve an MDP by policy iteration [Fig. 17.7]


def policy_evaluation(pi, U, mdp, k=<NUM_LIT:20>):

R, T, gamma = mdp.R, mdp.T, mdp.gamma<EOL>for i in range(k):<EOL><INDENT>for s in mdp.states:<EOL><INDENT>U[s] = R(s) + gamma * sum([p * U[s1] for (p, s1) in T(s, pi[s])])<EOL><DEDENT><DEDENT>return U<EOL>

Return an updated utility mapping U from each state in the MDP to its
    utility, using an approximation (modified policy iteration).


return self.reward[state]<EOL>


abstract<EOL>

Transition model.  From a state and an action, return a list
        of (probability, result-state) pairs.


if state in self.terminals:<EOL><INDENT>return [None]<EOL><DEDENT>else:<EOL><INDENT>return self.actlist<EOL><DEDENT>

Set of actions that can be performed in this state.  By default, a
        fixed list of actions, except for terminal states. Override this
        method if you need to specialize by state.


state1 = vector_add(state, direction)<EOL>return if_(state1 in self.states, state1, state)<EOL>

Return the state that results from going in this direction.


return list(reversed([[mapping.get((x,y), None)<EOL>for x in range(self.cols)]<EOL>for y in range(self.rows)]))<EOL>

Convert a mapping from (x, y) to v into a [[..., v, ...]] grid.


lines = [line for line in input.splitlines() if line.strip()]<EOL>return [list(map(num_or_str, line.split(delim))) for line in lines]<EOL>

r"""Input is a string consisting of lines, each line has comma-delimited
    fields.  Convert this into a list of lists.  Blank lines are skipped.
    Fields that look like numbers are converted to numbers.
    The delim defaults to ',' but '\t' and None are also reasonable values.
    >>> parse_csv('1, 2, 3 \n 0, 2, na')
    [[1, 2, 3], [0, 2, 'na']]


most_popular = mode([e[dataset.target] for e in dataset.examples])<EOL>def predict(example):<EOL><INDENT>"<STR_LIT>"<EOL>return most_popular<EOL><DEDENT>return predict<EOL>

A very dumb algorithm: always pick the result that was most popular
    in the training data.  Makes a baseline for comparison.


targetvals = dataset.values[dataset.target]<EOL>target_dist = CountingProbDist(targetvals)<EOL>attr_dists = dict(((gv, attr), CountingProbDist(dataset.values[attr]))<EOL>for gv in targetvals<EOL>for attr in dataset.inputs)<EOL>for example in dataset.examples:<EOL><INDENT>targetval = example[dataset.target]<EOL>target_dist.add(targetval)<EOL>for attr in dataset.inputs:<EOL><INDENT>attr_dists[targetval, attr].add(example[attr])<EOL><DEDENT><DEDENT>def predict(example):<EOL><INDENT>"""<STR_LIT>"""<EOL>def class_probability(targetval):<EOL><INDENT>return (target_dist[targetval]<EOL>* product(attr_dists[targetval, attr][example[attr]]<EOL>for attr in dataset.inputs))<EOL><DEDENT>return argmax(targetvals, class_probability)<EOL><DEDENT>return predict<EOL>

Just count how many times each value of each input attribute
    occurs, conditional on the target value. Count the different
    target values too.


def predict(example):<EOL><INDENT>"<STR_LIT>"<EOL>best = heapq.nsmallest(k, ((dataset.distance(e, example), e)<EOL>for e in dataset.examples))<EOL>return mode(e[dataset.target] for (d, e) in best)<EOL><DEDENT>return predict<EOL>

k-NearestNeighbor: the k nearest neighbors vote.


target, values = dataset.target, dataset.values<EOL>def decision_tree_learning(examples, attrs, parent_examples=()):<EOL><INDENT>if len(examples) == <NUM_LIT:0>:<EOL><INDENT>return plurality_value(parent_examples)<EOL><DEDENT>elif all_same_class(examples):<EOL><INDENT>return DecisionLeaf(examples[<NUM_LIT:0>][target])<EOL><DEDENT>elif len(attrs) == <NUM_LIT:0>:<EOL><INDENT>return plurality_value(examples)<EOL><DEDENT>else:<EOL><INDENT>A = choose_attribute(attrs, examples)<EOL>tree = DecisionFork(A, dataset.attrnames[A])<EOL>for (v_k, exs) in split_by(A, examples):<EOL><INDENT>subtree = decision_tree_learning(<EOL>exs, removeall(A, attrs), examples)<EOL>tree.add(v_k, subtree)<EOL><DEDENT>return tree<EOL><DEDENT><DEDENT>def plurality_value(examples):<EOL><INDENT>"""<STR_LIT>"""<EOL>popular = argmax_random_tie(values[target],<EOL>lambda v: count(target, v, examples))<EOL>return DecisionLeaf(popular)<EOL><DEDENT>def count(attr, val, examples):<EOL><INDENT>return count_if(lambda e: e[attr] == val, examples)<EOL><DEDENT>def all_same_class(examples):<EOL><INDENT>"<STR_LIT>"<EOL>class0 = examples[<NUM_LIT:0>][target]<EOL>return all(e[target] == class0 for e in examples)<EOL><DEDENT>def choose_attribute(attrs, examples):<EOL><INDENT>"<STR_LIT>"<EOL>return argmax_random_tie(attrs,<EOL>lambda a: information_gain(a, examples))<EOL><DEDENT>def information_gain(attr, examples):<EOL><INDENT>"<STR_LIT>"<EOL>def I(examples):<EOL><INDENT>return information_content([count(target, v, examples)<EOL>for v in values[target]])<EOL><DEDENT>N = float(len(examples))<EOL>remainder = sum((len(examples_i) / N) * I(examples_i)<EOL>for (v, examples_i) in split_by(attr, examples))<EOL>return I(examples) - remainder<EOL><DEDENT>def split_by(attr, examples):<EOL><INDENT>"<STR_LIT>"<EOL>return [(v, [e for e in examples if e[attr] == v])<EOL>for v in values[attr]]<EOL><DEDENT>return decision_tree_learning(dataset.examples, dataset.inputs)<EOL>


probabilities = normalize(removeall(<NUM_LIT:0>, values))<EOL>return sum(-p * log2(p) for p in probabilities)<EOL>

Number of bits to represent the probability distribution in values.


def decision_list_learning(examples):<EOL><INDENT>if not examples:<EOL><INDENT>return [(True, False)]<EOL><DEDENT>t, o, examples_t = find_examples(examples)<EOL>if not t:<EOL><INDENT>raise Failure<EOL><DEDENT>return [(t, o)] + decision_list_learning(examples - examples_t)<EOL><DEDENT>def find_examples(examples):<EOL><INDENT>"""<STR_LIT>"""<EOL>unimplemented()<EOL><DEDENT>def passes(example, test):<EOL><INDENT>"<STR_LIT>"<EOL>unimplemented()<EOL><DEDENT>def predict(example):<EOL><INDENT>"<STR_LIT>"<EOL>for test, outcome in predict.decision_list:<EOL><INDENT>if passes(example, test):<EOL><INDENT>return outcome<EOL><DEDENT><DEDENT><DEDENT>predict.decision_list = decision_list_learning(set(dataset.examples))<EOL>return predict<EOL>


activations = [[<NUM_LIT:0.0> for i in range(n)] for n in sizes]<EOL>weights = []<EOL>def predict(example):<EOL><INDENT>unimplemented()<EOL><DEDENT>return predict<EOL>


unimplemented()<EOL>


def train(dataset):<EOL><INDENT>predictors = [learner(dataset) for learner in learners]<EOL>def predict(example):<EOL><INDENT>return mode(predictor(example) for predictor in predictors)<EOL><DEDENT>return predict<EOL><DEDENT>return train<EOL>

Given a list of learning algorithms, have them vote.


def train(dataset):<EOL><INDENT>examples, target = dataset.examples, dataset.target<EOL>N = len(examples)<EOL>epsilon = <NUM_LIT:1.>/(<NUM_LIT:2>*N)<EOL>w = [<NUM_LIT:1.>/N] * N<EOL>h, z = [], []<EOL>for k in range(K):<EOL><INDENT>h_k = L(dataset, w)<EOL>h.append(h_k)<EOL>error = sum(weight for example, weight in zip(examples, w)<EOL>if example[target] != h_k(example))<EOL>error = clip(error, epsilon, <NUM_LIT:1>-epsilon)<EOL>for j, example in enumerate(examples):<EOL><INDENT>if example[target] == h_k(example):<EOL><INDENT>w[j] *= error / (<NUM_LIT:1.> - error)<EOL><DEDENT><DEDENT>w = normalize(w)<EOL>z.append(math.log((<NUM_LIT:1.> - error) / error))<EOL><DEDENT>return WeightedMajority(h, z)<EOL><DEDENT>return train<EOL>


def predict(example):<EOL><INDENT>return weighted_mode((predictor(example) for predictor in predictors),<EOL>weights)<EOL><DEDENT>return predict<EOL>

Return a predictor that takes a weighted vote.


totals = defaultdict(int)<EOL>for v, w in zip(values, weights):<EOL><INDENT>totals[v] += w<EOL><DEDENT>return max(list(totals.keys()), key=totals.get)<EOL>

Return the value with the greatest total weight.
    >>> weighted_mode('abbaa', [1,2,3,1,2])
    'b


def train(dataset, weights):<EOL><INDENT>return unweighted_learner(replicated_dataset(dataset, weights))<EOL><DEDENT>return train<EOL>

Given a learner that takes just an unweighted dataset, return
    one that takes also a weight for each example. [p. 749 footnote 14]


def replicated_dataset(dataset, weights, n=None):

n = n or len(dataset.examples)<EOL>result = copy.copy(dataset)<EOL>result.examples = weighted_replicate(dataset.examples, weights, n)<EOL>return result<EOL>

Copy dataset, replicating each example in proportion to its weight.


def weighted_replicate(seq, weights, n):

assert len(seq) == len(weights)<EOL>weights = normalize(weights)<EOL>wholes = [int(w*n) for w in weights]<EOL>fractions = [(w*n) % <NUM_LIT:1> for w in weights]<EOL>return (flatten([x] * nx for x, nx in zip(seq, wholes))<EOL>+ weighted_sample_with_replacement(seq, fractions, n - sum(wholes)))<EOL>

Return n selections from seq, with the count of each element of
    seq proportional to the corresponding weight (filling in fractions
    randomly).
    >>> weighted_replicate('ABC', [1,2,1], 4)
    ['A', 'B', 'B', 'C']


def cross_validation(learner, dataset, k=<NUM_LIT:10>, trials=<NUM_LIT:1>):

if k is None:<EOL><INDENT>k = len(dataset.examples)<EOL><DEDENT>if trials > <NUM_LIT:1>:<EOL><INDENT>return mean([cross_validation(learner, dataset, k, trials=<NUM_LIT:1>)<EOL>for t in range(trials)])<EOL><DEDENT>else:<EOL><INDENT>n = len(dataset.examples)<EOL>random.shuffle(dataset.examples)<EOL>return mean([train_and_test(learner, dataset, i*(n/k), (i+<NUM_LIT:1>)*(n/k))<EOL>for i in range(k)])<EOL><DEDENT>

Do k-fold cross_validate and return their mean.
    That is, keep out 1/k of the examples for testing on each of k runs.
    Shuffle the examples first; If trials>1, average over several shuffles.


return cross_validation(learner, dataset, k=len(dataset.examples))<EOL>

Leave one out cross-validation over the dataset.


return DataSet(name='<STR_LIT>', target='<STR_LIT>', examples=examples,<EOL>attrnames='<STR_LIT>'<EOL>+ '<STR_LIT>')<EOL>

Build a DataSet of Restaurant waiting examples. [Fig. 18.3]


def gen():<EOL><INDENT>example = list(map(random.choice, restaurant.values))<EOL>example[restaurant.target] = Fig[<NUM_LIT>,<NUM_LIT:2>](example)<EOL>return example<EOL><DEDENT>return RestaurantDataSet([gen() for i in range(n)])<EOL>


examples = []<EOL>for i in range(n):<EOL><INDENT>bits = [random.choice([<NUM_LIT:0>, <NUM_LIT:1>]) for i in range(k)]<EOL>bits.append(int(sum(bits) > k/<NUM_LIT:2>))<EOL>examples.append(bits)<EOL><DEDENT>return DataSet(name="<STR_LIT>", examples=examples)<EOL>

Return a DataSet with n k-bit examples of the majority problem:
    k random bits followed by a 1 if more than half the bits are 1, else 0.


examples = []<EOL>for i in range(n):<EOL><INDENT>bits = [random.choice([<NUM_LIT:0>, <NUM_LIT:1>]) for i in range(k)]<EOL>bits.append(sum(bits) % <NUM_LIT:2>)<EOL>examples.append(bits)<EOL><DEDENT>return DataSet(name=name, examples=examples)<EOL>

Return a DataSet with n k-bit examples of the parity problem:
    k random bits followed by a 1 if an odd number of bits are 1, else 0.


return Parity(<NUM_LIT:2>, n, name="<STR_LIT>")<EOL>

Return a DataSet with n examples of 2-input xor.


examples = []<EOL>for i in range(n):<EOL><INDENT>x, y = [random.uniform(<NUM_LIT:0.0>, <NUM_LIT>) for i in '<STR_LIT>']<EOL>examples.append([x, y, int(x) != int(y)])<EOL><DEDENT>return DataSet(name="<STR_LIT>", examples=examples)<EOL>

2 inputs are chosen uniformly from (0.0 .. 2.0]; output is xor of ints.


def compare(algorithms=[PluralityLearner, NaiveBayesLearner,<EOL>NearestNeighborLearner, DecisionTreeLearner],<EOL>datasets=[iris, orings, zoo, restaurant, SyntheticRestaurant(<NUM_LIT:20>),<EOL>Majority(<NUM_LIT:7>, <NUM_LIT:100>), Parity(<NUM_LIT:7>, <NUM_LIT:100>), Xor(<NUM_LIT:100>)],<EOL>k=<NUM_LIT:10>, trials=<NUM_LIT:1>):

print_table([[a.__name__.replace('<STR_LIT>','<STR_LIT>')] +<EOL>[cross_validation(a, d, k, trials) for d in datasets]<EOL>for a in algorithms],<EOL>header=['<STR_LIT>'] + [d.name[<NUM_LIT:0>:<NUM_LIT:7>] for d in datasets], numfmt='<STR_LIT>')<EOL>

Compare various learners on various datasets using cross-validation.
    Print results as a table.


def __init__(self, examples=None, attrs=None, attrnames=None, target=-<NUM_LIT:1>,<EOL>inputs=None, values=None, distance=mean_boolean_error,<EOL>name='<STR_LIT>', source='<STR_LIT>', exclude=()):

update(self, name=name, source=source, values=values, distance=distance)<EOL>if isinstance(examples, str):<EOL><INDENT>self.examples = parse_csv(examples)<EOL><DEDENT>elif examples is None:<EOL><INDENT>self.examples = parse_csv(DataFile(name+'<STR_LIT>').read())<EOL><DEDENT>else:<EOL><INDENT>self.examples = examples<EOL><DEDENT>if not attrs and self.examples:<EOL><INDENT>attrs = list(range(len(self.examples[<NUM_LIT:0>])))<EOL><DEDENT>self.attrs = attrs<EOL>if isinstance(attrnames, str):<EOL><INDENT>self.attrnames = attrnames.split()<EOL><DEDENT>else:<EOL><INDENT>self.attrnames = attrnames or attrs<EOL><DEDENT>self.setproblem(target, inputs=inputs, exclude=exclude)<EOL>

Accepts any of DataSet's fields.  Examples can also be a
        string or file from which to parse examples using parse_csv.
        Optional parameter: exclude, as documented in .setproblem().
        >>> DataSet(examples='1, 2, 3')
        <DataSet(): 1 examples, 3 attributes>


def setproblem(self, target, inputs=None, exclude=()):

self.target = self.attrnum(target)<EOL>exclude = list(map(self.attrnum, exclude))<EOL>if inputs:<EOL><INDENT>self.inputs = removeall(self.target, inputs)<EOL><DEDENT>else:<EOL><INDENT>self.inputs = [a for a in self.attrs<EOL>if a != self.target and a not in exclude]<EOL><DEDENT>if not self.values:<EOL><INDENT>self.values = list(map(unique, list(zip(*self.examples))))<EOL><DEDENT>self.check_me()<EOL>

Set (or change) the target and/or inputs.
        This way, one DataSet can be used multiple ways. inputs, if specified,
        is a list of attributes, or specify exclude as a list of attributes
        to not use in inputs. Attributes can be -n .. n, or an attrname.
        Also computes the list of possible values, if that wasn't done yet.


assert len(self.attrnames) == len(self.attrs)<EOL>assert self.target in self.attrs<EOL>assert self.target not in self.inputs<EOL>assert set(self.inputs).issubset(set(self.attrs))<EOL>list(map(self.check_example, self.examples))<EOL>


self.check_example(example)<EOL>self.examples.append(example)<EOL>

Add an example to the list of examples, checking it first.


if self.values:<EOL><INDENT>for a in self.attrs:<EOL><INDENT>if example[a] not in self.values[a]:<EOL><INDENT>raise ValueError('<STR_LIT>' %<EOL>(example[a], self.attrnames[a], example))<EOL><DEDENT><DEDENT><DEDENT>

Raise ValueError if example has any invalid values.


if attr < <NUM_LIT:0>:<EOL><INDENT>return len(self.attrs) + attr<EOL><DEDENT>elif isinstance(attr, str):<EOL><INDENT>return self.attrnames.index(attr)<EOL><DEDENT>else:<EOL><INDENT>return attr<EOL><DEDENT>

Returns the number used for attr, which can be a name, or -n .. n-1.


return [attr_i if i in self.inputs else None<EOL>for i, attr_i in enumerate(example)]<EOL>

Return a copy of example, with non-input attributes replaced by None.


def __init__(self, observations=[], default=<NUM_LIT:0>):

update(self, dictionary={}, n_obs=<NUM_LIT:0.0>, default=default, sampler=None)<EOL>for o in observations:<EOL><INDENT>self.add(o)<EOL><DEDENT>

Create a distribution, and optionally add in some observations.
        By default this is an unsmoothed distribution, but saying default=1,
        for example, gives you add-one smoothing.


self.smooth_for(o)<EOL>self.dictionary[o] += <NUM_LIT:1><EOL>self.n_obs += <NUM_LIT:1><EOL>self.sampler = None<EOL>

Add an observation o to the distribution.


if o not in self.dictionary:<EOL><INDENT>self.dictionary[o] = self.default<EOL>self.n_obs += self.default<EOL>self.sampler = None<EOL><DEDENT>

Include o among the possible observations, whether or not
        it's been observed yet.


self.smooth_for(item)<EOL>return self.dictionary[item] / self.n_obs<EOL>

Return an estimate of the probability of item.


return heapq.nlargest(n, [(v, k) for (k, v) in list(self.dictionary.items())])<EOL>

Return (count, obs) tuples for the n most frequent observations.


if self.sampler is None:<EOL><INDENT>self.sampler = weighted_sampler(list(self.dictionary.keys()),<EOL>list(self.dictionary.values()))<EOL><DEDENT>return self.sampler()<EOL>

Return a random sample from the distribution.


def __init__(self, attr, attrname=None, branches=None):

update(self, attr=attr, attrname=attrname or attr,<EOL>branches=branches or {})<EOL>

Initialize by saying what attribute this node tests.


attrvalue = example[self.attr]<EOL>return self.branches[attrvalue](example)<EOL>

Given an example, classify it using the attribute and the branches.


self.branches[val] = subtree<EOL>

Add a branch.  If self.attr = val, go to the given subtree.


def AC3(csp, queue=None, removals=None):

if queue is None:<EOL><INDENT>queue = [(Xi, Xk) for Xi in csp.vars for Xk in csp.neighbors[Xi]]<EOL><DEDENT>csp.support_pruning()<EOL>while queue:<EOL><INDENT>(Xi, Xj) = queue.pop()<EOL>if revise(csp, Xi, Xj, removals):<EOL><INDENT>if not csp.curr_domains[Xi]:<EOL><INDENT>return False<EOL><DEDENT>for Xk in csp.neighbors[Xi]:<EOL><INDENT>if Xk != Xi:<EOL><INDENT>queue.append((Xk, Xi))<EOL><DEDENT><DEDENT><DEDENT><DEDENT>return True<EOL>


revised = False<EOL>for x in csp.curr_domains[Xi][:]:<EOL><INDENT>if every(lambda y: not csp.constraints(Xi, x, Xj, y),<EOL>csp.curr_domains[Xj]):<EOL><INDENT>csp.prune(Xi, x, removals)<EOL>revised = True<EOL><DEDENT><DEDENT>return revised<EOL>


return find_if(lambda var: var not in assignment, csp.vars)<EOL>


return argmin_random_tie(<EOL>[v for v in csp.vars if v not in assignment],<EOL>lambda var: num_legal_values(csp, var, assignment))<EOL>


def unordered_domain_values(var, assignment, csp):

return csp.choices(var)<EOL>


return sorted(csp.choices(var),<EOL>key=lambda val: csp.nconflicts(var, val, assignment))<EOL>


def forward_checking(csp, var, value, assignment, removals):

for B in csp.neighbors[var]:<EOL><INDENT>if B not in assignment:<EOL><INDENT>for b in csp.curr_domains[B][:]:<EOL><INDENT>if not csp.constraints(var, value, B, b):<EOL><INDENT>csp.prune(B, b, removals)<EOL><DEDENT><DEDENT>if not csp.curr_domains[B]:<EOL><INDENT>return False<EOL><DEDENT><DEDENT><DEDENT>return True<EOL>

Prune neighbor values inconsistent with var=value.


def mac(csp, var, value, assignment, removals):

return AC3(csp, [(X, var) for X in csp.neighbors[var]], removals)<EOL>


def backtracking_search(csp,<EOL>select_unassigned_variable = first_unassigned_variable,<EOL>order_domain_values = unordered_domain_values,<EOL>inference = no_inference):

def backtrack(assignment):<EOL><INDENT>if len(assignment) == len(csp.vars):<EOL><INDENT>return assignment<EOL><DEDENT>var = select_unassigned_variable(assignment, csp)<EOL>for value in order_domain_values(var, assignment, csp):<EOL><INDENT>if <NUM_LIT:0> == csp.nconflicts(var, value, assignment):<EOL><INDENT>csp.assign(var, value, assignment)<EOL>removals = csp.suppose(var, value)<EOL>if inference(csp, var, value, assignment, removals):<EOL><INDENT>result = backtrack(assignment)<EOL>if result is not None:<EOL><INDENT>return result<EOL><DEDENT><DEDENT>csp.restore(removals)<EOL><DEDENT><DEDENT>csp.unassign(var, assignment)<EOL>return None<EOL><DEDENT>result = backtrack({})<EOL>assert result is None or csp.goal_test(result)<EOL>return result<EOL>

[Fig. 6.5]
    >>> backtracking_search(australia) is not None
    True
    >>> backtracking_search(australia, select_unassigned_variable=mrv) is not None
    True
    >>> backtracking_search(australia, order_domain_values=lcv) is not None
    True
    >>> backtracking_search(australia, select_unassigned_variable=mrv, order_domain_values=lcv) is not None
    True
    >>> backtracking_search(australia, inference=forward_checking) is not None
    True
    >>> backtracking_search(australia, inference=mac) is not None
    True
    >>> backtracking_search(usa, select_unassigned_variable=mrv, order_domain_values=lcv, inference=mac) is not None
    True


<EOL>csp.current = current = {}<EOL>for var in csp.vars:<EOL><INDENT>val = min_conflicts_value(csp, var, current)<EOL>csp.assign(var, val, current)<EOL><DEDENT>for i in range(max_steps):<EOL><INDENT>conflicted = csp.conflicted_vars(current)<EOL>if not conflicted:<EOL><INDENT>return current<EOL><DEDENT>var = random.choice(conflicted)<EOL>val = min_conflicts_value(csp, var, current)<EOL>csp.assign(var, val, current)<EOL><DEDENT>return None<EOL>

Solve a CSP by stochastic hillclimbing on the number of conflicts.


def min_conflicts_value(csp, var, current):

return argmin_random_tie(csp.domains[var],<EOL>lambda val: csp.nconflicts(var, val, current))<EOL>

Return the value that will give var the least number of conflicts.
    If there is a tie, choose at random.


n = len(csp.vars)<EOL>assignment = {}<EOL>root = csp.vars[<NUM_LIT:0>]<EOL>X, parent = topological_sort(csp.vars, root)<EOL>for Xj in reversed(X):<EOL><INDENT>if not make_arc_consistent(parent[Xj], Xj, csp):<EOL><INDENT>return None<EOL><DEDENT><DEDENT>for Xi in X:<EOL><INDENT>if not csp.curr_domains[Xi]:<EOL><INDENT>return None<EOL><DEDENT>assignment[Xi] = csp.curr_domains[Xi][<NUM_LIT:0>]<EOL><DEDENT>return assignment<EOL>


def different_values_constraint(A, a, B, b):

return a != b<EOL>

A constraint saying two neighboring variables must differ in value.


if isinstance(neighbors, str):<EOL><INDENT>neighbors = parse_neighbors(neighbors)<EOL><DEDENT>return CSP(list(neighbors.keys()), UniversalDict(colors), neighbors,<EOL>different_values_constraint)<EOL>

Make a CSP for the problem of coloring a map with different colors
    for any two adjacent regions.  Arguments are a list of colors, and a
    dict of {region: [neighbor,...]} entries.  This dict may also be
    specified as a string of the form defined by parse_neighbors.


dict = DefaultDict([])<EOL>for var in vars:<EOL><INDENT>dict[var] = []<EOL><DEDENT>specs = [spec.split('<STR_LIT::>') for spec in neighbors.split('<STR_LIT:;>')]<EOL>for (A, Aneighbors) in specs:<EOL><INDENT>A = A.strip()<EOL>dict.setdefault(A, [])<EOL>for B in Aneighbors.split():<EOL><INDENT>dict[A].append(B)<EOL>dict[B].append(A)<EOL><DEDENT><DEDENT>return dict<EOL>

Convert a string of the form 'X: Y Z; Y: Z' into a dict mapping
    regions to neighbors.  The syntax is a region name followed by a ':'
    followed by zero or more region names, followed by ';', repeated for
    each region name.  If you say 'X: Y' you don't need 'Y: X'.
    >>> parse_neighbors('X: Y Z; Y: Z')
    {'Y': ['X', 'Z'], 'X': ['Y', 'Z'], 'Z': ['X', 'Y']}


return A == B or (a != b and A + a != B + b and A - a != B - b)<EOL>

Constraint is satisfied (true) if A, B are really the same variable,
    or if they are not in the same row, down diagonal, or up diagonal.


Colors = '<STR_LIT>'.split()<EOL>Pets = '<STR_LIT>'.split()<EOL>Drinks = '<STR_LIT>'.split()<EOL>Countries = '<STR_LIT>'.split()<EOL>Smokes = '<STR_LIT>'.split()<EOL>vars = Colors + Pets + Drinks + Countries + Smokes<EOL>domains = {}<EOL>for var in vars:<EOL><INDENT>domains[var] = list(range(<NUM_LIT:1>, <NUM_LIT:6>))<EOL><DEDENT>domains['<STR_LIT>'] = [<NUM_LIT:1>]<EOL>domains['<STR_LIT>'] = [<NUM_LIT:3>]<EOL>neighbors = parse_neighbors("""<STR_LIT>""", vars)<EOL>for type in [Colors, Pets, Drinks, Countries, Smokes]:<EOL><INDENT>for A in type:<EOL><INDENT>for B in type:<EOL><INDENT>if A != B:<EOL><INDENT>if B not in neighbors[A]: neighbors[A].append(B)<EOL>if A not in neighbors[B]: neighbors[B].append(A)<EOL><DEDENT><DEDENT><DEDENT><DEDENT>def zebra_constraint(A, a, B, b, recurse=<NUM_LIT:0>):<EOL><INDENT>same = (a == b)<EOL>next_to = abs(a - b) == <NUM_LIT:1><EOL>if A == '<STR_LIT>' and B == '<STR_LIT>': return same<EOL>if A == '<STR_LIT>' and B == '<STR_LIT>': return same<EOL>if A == '<STR_LIT>' and B == '<STR_LIT>': return next_to<EOL>if A == '<STR_LIT>' and B == '<STR_LIT>': return next_to<EOL>if A == '<STR_LIT>' and B == '<STR_LIT>': return same<EOL>if A == '<STR_LIT>' and B == '<STR_LIT>': return same<EOL>if A == '<STR_LIT>' and B == '<STR_LIT>': return same<EOL>if A == '<STR_LIT>' and B == '<STR_LIT>': return same<EOL>if A == '<STR_LIT>' and B == '<STR_LIT>': return same<EOL>if A == '<STR_LIT>' and B == '<STR_LIT>': return next_to<EOL>if A == '<STR_LIT>' and B == '<STR_LIT>': return same<EOL>if A == '<STR_LIT>' and B == '<STR_LIT>': return (a - <NUM_LIT:1>) == b<EOL>if recurse == <NUM_LIT:0>: return zebra_constraint(B, b, A, a, <NUM_LIT:1>)<EOL>if ((A in Colors and B in Colors) or<EOL>(A in Pets and B in Pets) or<EOL>(A in Drinks and B in Drinks) or<EOL>(A in Countries and B in Countries) or<EOL>(A in Smokes and B in Smokes)): return not same<EOL>raise '<STR_LIT:error>'<EOL><DEDENT>return CSP(vars, domains, neighbors, zebra_constraint)<EOL>


def __init__(self, vars, domains, neighbors, constraints):

vars = vars or list(domains.keys())<EOL>update(self, vars=vars, domains=domains,<EOL>neighbors=neighbors, constraints=constraints,<EOL>initial=(), curr_domains=None, nassigns=<NUM_LIT:0>)<EOL>

Construct a CSP problem. If vars is empty, it becomes domains.keys().


assignment[var] = val<EOL>self.nassigns += <NUM_LIT:1><EOL>

Add {var: val} to assignment; Discard the old value if any.


if var in assignment:<EOL><INDENT>del assignment[var]<EOL><DEDENT>

Remove {var: val} from assignment.
        DO NOT call this if you are changing a variable to a new value;
        just call assign for that.


def nconflicts(self, var, val, assignment):

<EOL>def conflict(var2):<EOL><INDENT>return (var2 in assignment<EOL>and not self.constraints(var, val, var2, assignment[var2]))<EOL><DEDENT>return count_if(conflict, self.neighbors[var])<EOL>

Return the number of conflicts var=val has with other variables.


<EOL>print('<STR_LIT>', self, '<STR_LIT>', assignment)<EOL>

Show a human-readable representation of the CSP.


if len(state) == len(self.vars):<EOL><INDENT>return []<EOL><DEDENT>else:<EOL><INDENT>assignment = dict(state)<EOL>var = find_if(lambda v: v not in assignment, self.vars)<EOL>return [(var, val) for val in self.domains[var]<EOL>if self.nconflicts(var, val, assignment) == <NUM_LIT:0>]<EOL><DEDENT>

Return a list of applicable actions: nonconflicting
        assignments to an unassigned variable.


def result(self, state, xxx_todo_changeme):

(var, val) = xxx_todo_changeme<EOL>return state + ((var, val),)<EOL>

Perform an action and return the new state.


if self.curr_domains is None:<EOL><INDENT>self.curr_domains = dict((v, list(self.domains[v]))<EOL>for v in self.vars)<EOL><DEDENT>

Make sure we can prune values from domains. (We want to pay
        for this only if we use it.)


self.support_pruning()<EOL>removals = [(var, a) for a in self.curr_domains[var] if a != value]<EOL>self.curr_domains[var] = [value]<EOL>return removals<EOL>

Start accumulating inferences from assuming var=value.


self.curr_domains[var].remove(value)<EOL>if removals is not None: removals.append((var, value))<EOL>


return (self.curr_domains or self.domains)[var]<EOL>

Return all values for var that aren't currently ruled out.


self.support_pruning()<EOL>return dict((v, self.curr_domains[v][<NUM_LIT:0>])<EOL>for v in self.vars if <NUM_LIT:1> == len(self.curr_domains[v]))<EOL>

Return the partial assignment implied by the current inferences.


for B, b in removals:<EOL><INDENT>self.curr_domains[B].append(b)<EOL><DEDENT>

Undo a supposition and all inferences from it.


return [var for var in self.vars<EOL>if self.nconflicts(var, current[var], current) > <NUM_LIT:0>]<EOL>

Return a list of variables in current assignment that are in conflict


CSP.__init__(self, list(range(n)), UniversalDict(list(range(n))),<EOL>UniversalDict(list(range(n))), queen_constraint)<EOL>update(self, rows=[<NUM_LIT:0>]*n, ups=[<NUM_LIT:0>]*(<NUM_LIT:2>*n - <NUM_LIT:1>), downs=[<NUM_LIT:0>]*(<NUM_LIT:2>*n - <NUM_LIT:1>))<EOL>

Initialize data structures for n Queens.


n = len(self.vars)<EOL>c = self.rows[val] + self.downs[var+val] + self.ups[var-val+n-<NUM_LIT:1>]<EOL>if assignment.get(var, None) == val:<EOL><INDENT>c -= <NUM_LIT:3><EOL><DEDENT>return c<EOL>

The number of conflicts, as recorded with each assignment.
        Count conflicts in row and in up, down diagonals. If there
        is a queen there, it can't conflict with itself, so subtract 3.


oldval = assignment.get(var, None)<EOL>if val != oldval:<EOL><INDENT>if oldval is not None: <EOL><INDENT>self.record_conflict(assignment, var, oldval, -<NUM_LIT:1>)<EOL><DEDENT>self.record_conflict(assignment, var, val, +<NUM_LIT:1>)<EOL>CSP.assign(self, var, val, assignment)<EOL><DEDENT>

Assign var, and keep track of conflicts.


if var in assignment:<EOL><INDENT>self.record_conflict(assignment, var, assignment[var], -<NUM_LIT:1>)<EOL><DEDENT>CSP.unassign(self, var, assignment)<EOL>

Remove var from assignment (if it is there) and track conflicts.


def record_conflict(self, assignment, var, val, delta):

n = len(self.vars)<EOL>self.rows[val] += delta<EOL>self.downs[var + val] += delta<EOL>self.ups[var - val + n - <NUM_LIT:1>] += delta<EOL>

Record conflicts caused by addition or deletion of a Queen.


n = len(self.vars)<EOL>for val in range(n):<EOL><INDENT>for var in range(n):<EOL><INDENT>if assignment.get(var,'<STR_LIT>') == val: ch = '<STR_LIT>'<EOL>elif (var+val) % <NUM_LIT:2> == <NUM_LIT:0>: ch = '<STR_LIT:.>'<EOL>else: ch = '<STR_LIT:->'<EOL>print(ch, end='<STR_LIT:U+0020>')<EOL><DEDENT>print('<STR_LIT:U+0020>', end='<STR_LIT:U+0020>')<EOL>for var in range(n):<EOL><INDENT>if assignment.get(var,'<STR_LIT>') == val: ch = '<STR_LIT:*>'<EOL>else: ch = '<STR_LIT:U+0020>'<EOL>print(str(self.nconflicts(var, val, assignment))+ch, end='<STR_LIT:U+0020>')<EOL><DEDENT>print()<EOL><DEDENT>

Print the queens and the nconflicts values (for debugging).


squares = iter(re.findall(r'<STR_LIT>', grid))<EOL>domains = dict((var, if_(ch in '<STR_LIT>', [ch], '<STR_LIT>'))<EOL>for var, ch in zip(flatten(self.rows), squares))<EOL>for _ in squares:<EOL><INDENT>raise ValueError("<STR_LIT>", grid) <EOL><DEDENT>CSP.__init__(self, None, domains, self.neighbors,<EOL>different_values_constraint)<EOL>

Build a Sudoku problem from a string representing the grid:
        the digits 1-9 denote a filled cell, '.' or '0' an empty one;
        other characters are ignored.


steps = itertools.count()<EOL>def program(percept):<EOL><INDENT>t = next(steps)<EOL>KB.tell(make_percept_sentence(percept, t))<EOL>action = KB.ask(make_action_query(t))<EOL>KB.tell(make_action_sentence(action, t))<EOL>return action<EOL><DEDENT>def make_percept_sentence(self, percept, t):<EOL><INDENT>return Expr("<STR_LIT>")(percept, t)<EOL><DEDENT>def make_action_query(self, t):<EOL><INDENT>return expr("<STR_LIT>" % t)<EOL><DEDENT>def make_action_sentence(self, action, t):<EOL><INDENT>return Expr("<STR_LIT>")(action[expr('<STR_LIT:action>')], t)<EOL><DEDENT>return program<EOL>

A generic logical knowledge-based agent program. [Fig. 7.1]


if isinstance(s, Expr): return s<EOL>if isnumber(s): return Expr(s)<EOL>s = s.replace('<STR_LIT>', '<STR_LIT>').replace('<STR_LIT>', '<STR_LIT>')<EOL>s = s.replace('<STR_LIT>', '<STR_LIT:%>').replace('<STR_LIT>', '<STR_LIT>')<EOL>s = re.sub(r'<STR_LIT>', r'<STR_LIT>', s)<EOL>return eval(s, {'<STR_LIT>':Expr})<EOL>

Create an Expr representing a logic expression by parsing the input
    string. Symbols and numbers are automatically converted to Exprs.
    In addition you can use alternative spellings of these operators:
      'x ==> y'   parses as   (x >> y)    # Implication
      'x <== y'   parses as   (x << y)    # Reverse implication
      'x <=> y'   parses as   (x % y)     # Logical equivalence
      'x =/= y'   parses as   (x ^ y)     # Logical disequality (xor)
    But BE CAREFUL; precedence of implication is wrong. expr('P & Q ==> R & S')
    is ((P & (Q >> R)) & S); so you must use expr('(P & Q) ==> (R & S)').
    >>> expr('P <=> Q(1)')
    (P <=> Q(1))
    >>> expr('P & Q | ~R(x, F(x))')
    ((P & Q) | ~R(x, F(x)))


return isinstance(s, str) and s[:<NUM_LIT:1>].isalpha()<EOL>

A string s is a symbol if it starts with an alphabetic char.


return is_symbol(s) and s[<NUM_LIT:0>].islower()<EOL>

A logic variable symbol is an initial-lowercase string.


return is_symbol(s) and s[<NUM_LIT:0>].isupper() and s != '<STR_LIT>' and s != '<STR_LIT>'<EOL>

A proposition logic symbol is an initial-uppercase string other than
    TRUE or FALSE.


result = set([])<EOL>def walk(s):<EOL><INDENT>if is_variable(s):<EOL><INDENT>result.add(s)<EOL><DEDENT>else:<EOL><INDENT>for arg in s.args:<EOL><INDENT>walk(arg)<EOL><DEDENT><DEDENT><DEDENT>walk(s)<EOL>return result<EOL>

Return a set of the variables in expression s.
    >>> ppset(variables(F(x, A, y)))
    set([x, y])
    >>> ppset(variables(F(G(x), z)))
    set([x, z])
    >>> ppset(variables(expr('F(x, x) & G(x, y) & H(y, z) & R(A, z, z)')))
    set([x, y, z])


if is_symbol(s.op):<EOL><INDENT>return True<EOL><DEDENT>elif s.op == '<STR_LIT>':<EOL><INDENT>antecedent, consequent = s.args<EOL>return (is_symbol(consequent.op)<EOL>and every(lambda arg: is_symbol(arg.op), conjuncts(antecedent)))<EOL><DEDENT>else:<EOL><INDENT>return False<EOL><DEDENT>

returns True for exprs s of the form A & B & ... & C ==> D,
    where all literals are positive.  In clause form, this is
    ~A | ~B | ... | ~C | D, where exactly one clause is positive.
    >>> is_definite_clause(expr('Farmer(Mac)'))
    True
    >>> is_definite_clause(expr('~Farmer(Mac)'))
    False
    >>> is_definite_clause(expr('(Farmer(f) & Rabbit(r)) ==> Hates(f, r)'))
    True
    >>> is_definite_clause(expr('(Farmer(f) & ~Rabbit(r)) ==> Hates(f, r)'))
    False
    >>> is_definite_clause(expr('(Farmer(f) | Rabbit(r)) ==> Hates(f, r)'))
    False


assert is_definite_clause(s)<EOL>if is_symbol(s.op):<EOL><INDENT>return [], s<EOL><DEDENT>else:<EOL><INDENT>antecedent, consequent = s.args<EOL>return conjuncts(antecedent), consequent<EOL><DEDENT>

Return the antecedents and the consequent of a definite clause.


assert not variables(alpha)<EOL>return tt_check_all(kb, alpha, prop_symbols(kb & alpha), {})<EOL>

Does kb entail the sentence alpha? Use truth tables. For propositional
    kb's and sentences. [Fig. 7.10]
    >>> tt_entails(expr('P & Q'), expr('Q'))
    True


def tt_check_all(kb, alpha, symbols, model):

if not symbols:<EOL><INDENT>if pl_true(kb, model):<EOL><INDENT>result = pl_true(alpha, model)<EOL>assert result in (True, False)<EOL>return result<EOL><DEDENT>else:<EOL><INDENT>return True<EOL><DEDENT><DEDENT>else:<EOL><INDENT>P, rest = symbols[<NUM_LIT:0>], symbols[<NUM_LIT:1>:]<EOL>return (tt_check_all(kb, alpha, rest, extend(model, P, True)) and<EOL>tt_check_all(kb, alpha, rest, extend(model, P, False)))<EOL><DEDENT>

Auxiliary routine to implement tt_entails.


if not isinstance(x, Expr):<EOL><INDENT>return []<EOL><DEDENT>elif is_prop_symbol(x.op):<EOL><INDENT>return [x]<EOL><DEDENT>else:<EOL><INDENT>return list(set(symbol for arg in x.args<EOL>for symbol in prop_symbols(arg)))<EOL><DEDENT>

Return a list of all propositional symbols in x.


return tt_entails(TRUE, expr(alpha))<EOL>

Is the propositional sentence alpha a tautology? (alpha will be
    coerced to an expr.)
    >>> tt_true(expr("(P >> Q) <=> (~P | Q)"))
    True


op, args = exp.op, exp.args<EOL>if exp == TRUE:<EOL><INDENT>return True<EOL><DEDENT>elif exp == FALSE:<EOL><INDENT>return False<EOL><DEDENT>elif is_prop_symbol(op):<EOL><INDENT>return model.get(exp)<EOL><DEDENT>elif op == '<STR_LIT>':<EOL><INDENT>p = pl_true(args[<NUM_LIT:0>], model)<EOL>if p is None: return None<EOL>else: return not p<EOL><DEDENT>elif op == '<STR_LIT:|>':<EOL><INDENT>result = False<EOL>for arg in args:<EOL><INDENT>p = pl_true(arg, model)<EOL>if p is True: return True<EOL>if p is None: result = None<EOL><DEDENT>return result<EOL><DEDENT>elif op == '<STR_LIT:&>':<EOL><INDENT>result = True<EOL>for arg in args:<EOL><INDENT>p = pl_true(arg, model)<EOL>if p is False: return False<EOL>if p is None: result = None<EOL><DEDENT>return result<EOL><DEDENT>p, q = args<EOL>if op == '<STR_LIT>':<EOL><INDENT>return pl_true(~p | q, model)<EOL><DEDENT>elif op == '<STR_LIT>':<EOL><INDENT>return pl_true(p | ~q, model)<EOL><DEDENT>pt = pl_true(p, model)<EOL>if pt is None: return None<EOL>qt = pl_true(q, model)<EOL>if qt is None: return None<EOL>if op == '<STR_LIT>':<EOL><INDENT>return pt == qt<EOL><DEDENT>elif op == '<STR_LIT>':<EOL><INDENT>return pt != qt<EOL><DEDENT>else:<EOL><INDENT>raise ValueError("<STR_LIT>" + str(exp))<EOL><DEDENT>

Return True if the propositional logic expression is true in the model,
    and False if it is false. If the model does not specify the value for
    every proposition, this may return None to indicate 'not obvious';
    this may happen even when the expression is tautological.


if isinstance(s, str): s = expr(s)<EOL>s = eliminate_implications(s) <EOL>s = move_not_inwards(s) <EOL>return distribute_and_over_or(s)<EOL>


if not s.args or is_symbol(s.op): return s     <EOL>args = list(map(eliminate_implications, s.args))<EOL>a, b = args[<NUM_LIT:0>], args[-<NUM_LIT:1>]<EOL>if s.op == '<STR_LIT>':<EOL><INDENT>return (b | ~a)<EOL><DEDENT>elif s.op == '<STR_LIT>':<EOL><INDENT>return (a | ~b)<EOL><DEDENT>elif s.op == '<STR_LIT>':<EOL><INDENT>return (a | ~b) & (b | ~a)<EOL><DEDENT>elif s.op == '<STR_LIT>':<EOL><INDENT>assert len(args) == <NUM_LIT:2>   <EOL>return (a & ~b) | (~a & b)<EOL><DEDENT>else:<EOL><INDENT>assert s.op in ('<STR_LIT:&>', '<STR_LIT:|>', '<STR_LIT>')<EOL>return Expr(s.op, *args)<EOL><DEDENT>

Change >>, <<, and <=> into &, |, and ~. That is, return an Expr
    that is equivalent to s, but has only &, |, and ~ as logical operators.
    >>> eliminate_implications(A >> (~B << C))
    ((~B | ~C) | ~A)
    >>> eliminate_implications(A ^ B)
    ((A & ~B) | (~A & B))


if s.op == '<STR_LIT>':<EOL><INDENT>NOT = lambda b: move_not_inwards(~b)<EOL>a = s.args[<NUM_LIT:0>]<EOL>if a.op == '<STR_LIT>': return move_not_inwards(a.args[<NUM_LIT:0>]) <EOL>if a.op =='<STR_LIT:&>': return associate('<STR_LIT:|>', list(map(NOT, a.args)))<EOL>if a.op =='<STR_LIT:|>': return associate('<STR_LIT:&>', list(map(NOT, a.args)))<EOL>return s<EOL><DEDENT>elif is_symbol(s.op) or not s.args:<EOL><INDENT>return s<EOL><DEDENT>else:<EOL><INDENT>return Expr(s.op, *list(map(move_not_inwards, s.args)))<EOL><DEDENT>

Rewrite sentence s by moving negation sign inward.
    >>> move_not_inwards(~(A | B))
    (~A & ~B)
    >>> move_not_inwards(~(A & B))
    (~A | ~B)
    >>> move_not_inwards(~(~(A | ~B) | ~~C))
    ((A | ~B) & ~C)


if s.op == '<STR_LIT:|>':<EOL><INDENT>s = associate('<STR_LIT:|>', s.args)<EOL>if s.op != '<STR_LIT:|>':<EOL><INDENT>return distribute_and_over_or(s)<EOL><DEDENT>if len(s.args) == <NUM_LIT:0>:<EOL><INDENT>return FALSE<EOL><DEDENT>if len(s.args) == <NUM_LIT:1>:<EOL><INDENT>return distribute_and_over_or(s.args[<NUM_LIT:0>])<EOL><DEDENT>conj = find_if((lambda d: d.op == '<STR_LIT:&>'), s.args)<EOL>if not conj:<EOL><INDENT>return s<EOL><DEDENT>others = [a for a in s.args if a is not conj]<EOL>rest = associate('<STR_LIT:|>', others)<EOL>return associate('<STR_LIT:&>', [distribute_and_over_or(c|rest)<EOL>for c in conj.args])<EOL><DEDENT>elif s.op == '<STR_LIT:&>':<EOL><INDENT>return associate('<STR_LIT:&>', list(map(distribute_and_over_or, s.args)))<EOL><DEDENT>else:<EOL><INDENT>return s<EOL><DEDENT>

Given a sentence s consisting of conjunctions and disjunctions
    of literals, return an equivalent sentence in CNF.
    >>> distribute_and_over_or((A & B) | C)
    ((A | C) & (B | C))


args = dissociate(op, args)<EOL>if len(args) == <NUM_LIT:0>:<EOL><INDENT>return _op_identity[op]<EOL><DEDENT>elif len(args) == <NUM_LIT:1>:<EOL><INDENT>return args[<NUM_LIT:0>]<EOL><DEDENT>else:<EOL><INDENT>return Expr(op, *args)<EOL><DEDENT>

Given an associative op, return an expression with the same
    meaning as Expr(op, *args), but flattened -- that is, with nested
    instances of the same op promoted to the top level.
    >>> associate('&', [(A&B),(B|C),(B&C)])
    (A & B & (B | C) & B & C)
    >>> associate('|', [A|(B|(C|(A&B)))])
    (A | B | C | (A & B))


result = []<EOL>def collect(subargs):<EOL><INDENT>for arg in subargs:<EOL><INDENT>if arg.op == op: collect(arg.args)<EOL>else: result.append(arg)<EOL><DEDENT><DEDENT>collect(args)<EOL>return result<EOL>

Given an associative op, return a flattened list result such
    that Expr(op, *result) means the same as Expr(op, *args).


return dissociate('<STR_LIT:&>', [s])<EOL>

Return a list of the conjuncts in the sentence s.
    >>> conjuncts(A & B)
    [A, B]
    >>> conjuncts(A | B)
    [(A | B)]


return dissociate('<STR_LIT:|>', [s])<EOL>

Return a list of the disjuncts in the sentence s.
    >>> disjuncts(A | B)
    [A, B]
    >>> disjuncts(A & B)
    [(A & B)]


clauses = KB.clauses + conjuncts(to_cnf(~alpha))<EOL>new = set()<EOL>while True:<EOL><INDENT>n = len(clauses)<EOL>pairs = [(clauses[i], clauses[j])<EOL>for i in range(n) for j in range(i+<NUM_LIT:1>, n)]<EOL>for (ci, cj) in pairs:<EOL><INDENT>resolvents = pl_resolve(ci, cj)<EOL>if FALSE in resolvents: return True<EOL>new = new.union(set(resolvents))<EOL><DEDENT>if new.issubset(set(clauses)): return False<EOL>for c in new:<EOL><INDENT>if c not in clauses: clauses.append(c)<EOL><DEDENT><DEDENT>

Propositional-logic resolution: say if alpha follows from KB. [Fig. 7.12]


clauses = []<EOL>for di in disjuncts(ci):<EOL><INDENT>for dj in disjuncts(cj):<EOL><INDENT>if di == ~dj or ~di == dj:<EOL><INDENT>dnew = unique(removeall(di, disjuncts(ci)) +<EOL>removeall(dj, disjuncts(cj)))<EOL>clauses.append(associate('<STR_LIT:|>', dnew))<EOL><DEDENT><DEDENT><DEDENT>return clauses<EOL>

Return all clauses that can be obtained by resolving clauses ci and cj.
    >>> for res in pl_resolve(to_cnf(A|B|C), to_cnf(~B|~C|F)):
    ...    ppset(disjuncts(res))
    set([A, C, F, ~C])
    set([A, B, F, ~B])


count = dict([(c, len(conjuncts(c.args[<NUM_LIT:0>]))) for c in KB.clauses<EOL>if c.op == '<STR_LIT>'])<EOL>inferred = DefaultDict(False)<EOL>agenda = [s for s in KB.clauses if is_prop_symbol(s.op)]<EOL>while agenda:<EOL><INDENT>p = agenda.pop()<EOL>if p == q: return True<EOL>if not inferred[p]:<EOL><INDENT>inferred[p] = True<EOL>for c in KB.clauses_with_premise(p):<EOL><INDENT>count[c] -= <NUM_LIT:1><EOL>if count[c] == <NUM_LIT:0>:<EOL><INDENT>agenda.append(c.args[<NUM_LIT:1>])<EOL><DEDENT><DEDENT><DEDENT><DEDENT>return False<EOL>

Use forward chaining to see if a PropDefiniteKB entails symbol q.
    [Fig. 7.15]
    >>> pl_fc_entails(Fig[7,15], expr('Q'))
    True


clauses = conjuncts(to_cnf(s))<EOL>symbols = prop_symbols(s)<EOL>return dpll(clauses, symbols, {})<EOL>

Check satisfiability of a propositional sentence.
    This differs from the book code in two ways: (1) it returns a model
    rather than True when it succeeds; this is more useful. (2) The
    function find_pure_symbol is passed a list of unknown clauses, rather
    than a list of all clauses and the model; this is more efficient.
    >>> ppsubst(dpll_satisfiable(A&~B))
    {A: True, B: False}
    >>> dpll_satisfiable(P&~P)
    False


unknown_clauses = [] <EOL>for c in clauses:<EOL><INDENT>val =  pl_true(c, model)<EOL>if val == False:<EOL><INDENT>return False<EOL><DEDENT>if val != True:<EOL><INDENT>unknown_clauses.append(c)<EOL><DEDENT><DEDENT>if not unknown_clauses:<EOL><INDENT>return model<EOL><DEDENT>P, value = find_pure_symbol(symbols, unknown_clauses)<EOL>if P:<EOL><INDENT>return dpll(clauses, removeall(P, symbols), extend(model, P, value))<EOL><DEDENT>P, value = find_unit_clause(clauses, model)<EOL>if P:<EOL><INDENT>return dpll(clauses, removeall(P, symbols), extend(model, P, value))<EOL><DEDENT>P, symbols = symbols[<NUM_LIT:0>], symbols[<NUM_LIT:1>:]<EOL>return (dpll(clauses, symbols, extend(model, P, True)) or<EOL>dpll(clauses, symbols, extend(model, P, False)))<EOL>

See if the clauses are true in a partial model.


for s in symbols:<EOL><INDENT>found_pos, found_neg = False, False<EOL>for c in clauses:<EOL><INDENT>if not found_pos and s in disjuncts(c): found_pos = True<EOL>if not found_neg and ~s in disjuncts(c): found_neg = True<EOL><DEDENT>if found_pos != found_neg: return s, found_pos<EOL><DEDENT>return None, None<EOL>

Find a symbol and its value if it appears only as a positive literal
    (or only as a negative) in clauses.
    >>> find_pure_symbol([A, B, C], [A|~B,~B|~C,C|A])
    (A, True)


for clause in clauses:<EOL><INDENT>P, value = unit_clause_assign(clause, model)<EOL>if P: return P, value<EOL><DEDENT>return None, None<EOL>

Find a forced assignment if possible from a clause with only 1
    variable not bound in the model.
    >>> find_unit_clause([A|B|C, B|~C, ~A|~B], {A:True})
    (B, False)


P, value = None, None<EOL>for literal in disjuncts(clause):<EOL><INDENT>sym, positive = inspect_literal(literal)<EOL>if sym in model:<EOL><INDENT>if model[sym] == positive:<EOL><INDENT>return None, None  <EOL><DEDENT><DEDENT>elif P:<EOL><INDENT>return None, None      <EOL><DEDENT>else:<EOL><INDENT>P, value = sym, positive<EOL><DEDENT><DEDENT>return P, value<EOL>

Return a single variable/value pair that makes clause true in
    the model, if possible.
    >>> unit_clause_assign(A|B|C, {A:True})
    (None, None)
    >>> unit_clause_assign(B|~C, {A:True})
    (None, None)
    >>> unit_clause_assign(~A|~B, {A:True})
    (B, False)


if literal.op == '<STR_LIT>':<EOL><INDENT>return literal.args[<NUM_LIT:0>], False<EOL><DEDENT>else:<EOL><INDENT>return literal, True<EOL><DEDENT>

The symbol in this literal, and the value it should take to
    make the literal true.
    >>> inspect_literal(P)
    (P, True)
    >>> inspect_literal(~P)
    (P, False)


def SAT_plan(init, transition, goal, t_max, SAT_solver=dpll_satisfiable):

for t in range(t_max):<EOL><INDENT>cnf = translate_to_SAT(init, transition, goal, t)<EOL>model = SAT_solver(cnf)<EOL>if model is not False:<EOL><INDENT>return extract_solution(model)<EOL><DEDENT><DEDENT>return None<EOL>


if s is None:<EOL><INDENT>return None<EOL><DEDENT>elif x == y:<EOL><INDENT>return s<EOL><DEDENT>elif is_variable(x):<EOL><INDENT>return unify_var(x, y, s)<EOL><DEDENT>elif is_variable(y):<EOL><INDENT>return unify_var(y, x, s)<EOL><DEDENT>elif isinstance(x, Expr) and isinstance(y, Expr):<EOL><INDENT>return unify(x.args, y.args, unify(x.op, y.op, s))<EOL><DEDENT>elif isinstance(x, str) or isinstance(y, str):<EOL><INDENT>return None<EOL><DEDENT>elif issequence(x) and issequence(y) and len(x) == len(y):<EOL><INDENT>if not x: return s<EOL>return unify(x[<NUM_LIT:1>:], y[<NUM_LIT:1>:], unify(x[<NUM_LIT:0>], y[<NUM_LIT:0>], s))<EOL><DEDENT>else:<EOL><INDENT>return None<EOL><DEDENT>

Unify expressions x,y with substitution s; return a substitution that
    would make x,y equal, or None if x,y can not unify. x and y can be
    variables (e.g. Expr('x')), constants, lists, or Exprs. [Fig. 9.1]
    >>> ppsubst(unify(x + y, y + C, {}))
    {x: y, y: C}


return isinstance(x, Expr) and not x.args and is_var_symbol(x.op)<EOL>

A variable is an Expr with no args and a lowercase symbol as the op.


if var == x:<EOL><INDENT>return True<EOL><DEDENT>elif is_variable(x) and x in s:<EOL><INDENT>return occur_check(var, s[x], s)<EOL><DEDENT>elif isinstance(x, Expr):<EOL><INDENT>return (occur_check(var, x.op, s) or<EOL>occur_check(var, x.args, s))<EOL><DEDENT>elif isinstance(x, (list, tuple)):<EOL><INDENT>return some(lambda element: occur_check(var, element, s), x)<EOL><DEDENT>else:<EOL><INDENT>return False<EOL><DEDENT>

Return true if variable var occurs anywhere in x
    (or in subst(s, x), if s has a binding for x).


s2 = s.copy()<EOL>s2[var] = val<EOL>return s2<EOL>

Copy the substitution s and extend it by setting var to val;
    return copy.
    >>> ppsubst(extend({x: 1}, y, 2))
    {x: 1, y: 2}


if isinstance(x, list):<EOL><INDENT>return [subst(s, xi) for xi in x]<EOL><DEDENT>elif isinstance(x, tuple):<EOL><INDENT>return tuple([subst(s, xi) for xi in x])<EOL><DEDENT>elif not isinstance(x, Expr):<EOL><INDENT>return x<EOL><DEDENT>elif is_var_symbol(x.op):<EOL><INDENT>return s.get(x, x)<EOL><DEDENT>else:<EOL><INDENT>return Expr(x.op, *[subst(s, arg) for arg in x.args])<EOL><DEDENT>

Substitute the substitution s into the expression x.
    >>> subst({x: 42, y:0}, F(x) + y)
    (F(42) + 0)


while True:<EOL><INDENT>new = {}<EOL>for r in KB.clauses:<EOL><INDENT>ps, q = parse_definite_clause(standardize_variables(r))<EOL>raise NotImplementedError<EOL><DEDENT><DEDENT>

Inefficient forward chaining for first-order logic. [Fig. 9.3]
    KB is a FolKB and alpha must be an atomic sentence.


if dic is None: dic = {}<EOL>if not isinstance(sentence, Expr):<EOL><INDENT>return sentence<EOL><DEDENT>elif is_var_symbol(sentence.op):<EOL><INDENT>if sentence in dic:<EOL><INDENT>return dic[sentence]<EOL><DEDENT>else:<EOL><INDENT>v = Expr('<STR_LIT>' % next(standardize_variables.counter))<EOL>dic[sentence] = v<EOL>return v<EOL><DEDENT><DEDENT>else:<EOL><INDENT>return Expr(sentence.op,<EOL>*[standardize_variables(a, dic) for a in sentence.args])<EOL><DEDENT>

Replace all the variables in sentence with new variables.
    >>> e = expr('F(a, b, c) & G(c, A, 23)')
    >>> len(variables(standardize_variables(e)))
    3
    >>> variables(e).intersection(variables(standardize_variables(e)))
    set([])
    >>> is_variable(standardize_variables(expr('x')))
    True


return fol_bc_or(KB, query, {})<EOL>

A simple backward-chaining algorithm for first-order logic. [Fig. 9.6]
    KB should be an instance of FolKB, and goals a list of literals.
    >>> test_ask('Farmer(x)')
    ['{x: Mac}']
    >>> test_ask('Human(x)')
    ['{x: Mac}', '{x: MrsMac}']
    >>> test_ask('Hates(x, y)')
    ['{x: Mac, y: MrsRabbit}', '{x: Mac, y: Pete}']
    >>> test_ask('Loves(x, y)')
    ['{x: MrsMac, y: Mac}', '{x: MrsRabbit, y: Pete}']
    >>> test_ask('Rabbit(x)')
    ['{x: MrsRabbit}', '{x: Pete}']
    >>> test_ask('Criminal(x)', crime_kb)
    ['{x: West}']


if y == x: return ONE<EOL>elif not y.args: return ZERO<EOL>else:<EOL><INDENT>u, op, v = y.args[<NUM_LIT:0>], y.op, y.args[-<NUM_LIT:1>]<EOL>if op == '<STR_LIT:+>': return diff(u, x) + diff(v, x)<EOL>elif op == '<STR_LIT:->' and len(args) == <NUM_LIT:1>: return -diff(u, x)<EOL>elif op == '<STR_LIT:->': return diff(u, x) - diff(v, x)<EOL>elif op == '<STR_LIT:*>': return u * diff(v, x) + v * diff(u, x)<EOL>elif op == '<STR_LIT:/>': return (v*diff(u, x) - u*diff(v, x)) / (v * v)<EOL>elif op == '<STR_LIT>' and isnumber(x.op):<EOL><INDENT>return (v * u ** (v - <NUM_LIT:1>) * diff(u, x))<EOL><DEDENT>elif op == '<STR_LIT>': return (v * u ** (v - <NUM_LIT:1>) * diff(u, x)<EOL>+ u ** v * Expr('<STR_LIT>')(u) * diff(v, x))<EOL>elif op == '<STR_LIT>': return diff(u, x) / u<EOL>else: raise ValueError("<STR_LIT>" % (op, y, x))<EOL><DEDENT>

Return the symbolic derivative, dy/dx, as an Expr.
    However, you probably want to simplify the results with simp.
    >>> diff(x * x, x)
    ((x * 1) + (x * 1))
    >>> simp(diff(x * x, x))
    (2 * x)


return simp(diff(y, x))<EOL>


return '<STR_LIT>' % '<STR_LIT:U+002CU+0020>'.join('<STR_LIT>' % (k, v)<EOL>for k, v in sorted(list(d.items()), key=repr))<EOL>

Return dictionary d's repr but with the items sorted.
    >>> pretty_dict({'m': 'M', 'a': 'A', 'r': 'R', 'k': 'K'})
    "{'a': 'A', 'k': 'K', 'm': 'M', 'r': 'R'}"
    >>> pretty_dict({z: C, y: B, x: A})
    '{x: A, y: B, z: C}'


return '<STR_LIT>' % sorted(s, key=repr)<EOL>

Return set s's repr but with the items sorted.
    >>> pretty_set(set(['A', 'Q', 'F', 'K', 'Y', 'B']))
    "set(['A', 'B', 'F', 'K', 'Q', 'Y'])"
    >>> pretty_set(set([z, y, x]))
    'set([x, y, z])'


ppdict(s)<EOL>


abstract<EOL>


for result in self.ask_generator(query):<EOL><INDENT>return result<EOL><DEDENT>return False<EOL>

Return a substitution that makes the query true, or,
        failing that, return False.


abstract<EOL>

Yield all the substitutions that make query true.


self.clauses.extend(conjuncts(to_cnf(sentence)))<EOL>


if tt_entails(Expr('<STR_LIT:&>', *self.clauses), query):<EOL><INDENT>yield {}<EOL><DEDENT>

Yield the empty substitution if KB implies query; else nothing.


for c in conjuncts(to_cnf(sentence)):<EOL><INDENT>if c in self.clauses:<EOL><INDENT>self.clauses.remove(c)<EOL><DEDENT><DEDENT>

Remove the sentence's clauses from the KB.


assert isinstance(op, str) or (isnumber(op) and not args)<EOL>self.op = num_or_str(op)<EOL>self.args = list(map(expr, args))<EOL>

Op is a string or number; args are Exprs (or are coerced to Exprs).


assert is_symbol(self.op) and not self.args<EOL>return Expr(self.op, *args)<EOL>

Self must be a symbol with no args, such as Expr('F').  Create a new
        Expr with 'F' as op and the args as arguments.


if not self.args:         <EOL><INDENT>return str(self.op)<EOL><DEDENT>elif is_symbol(self.op):  <EOL><INDENT>return '<STR_LIT>' % (self.op, '<STR_LIT:U+002CU+0020>'.join(map(repr, self.args)))<EOL><DEDENT>elif len(self.args) == <NUM_LIT:1>: <EOL><INDENT>return self.op + repr(self.args[<NUM_LIT:0>])<EOL><DEDENT>else:                     <EOL><INDENT>return '<STR_LIT>' % ('<STR_LIT:U+0020>'+self.op+'<STR_LIT:U+0020>').join(map(repr, self.args))<EOL><DEDENT>

Show something like 'P' or 'P(x, y)', or '~P' or '(P | Q | R)


return (other is self) or (isinstance(other, Expr)<EOL>and self.op == other.op and self.args == other.args)<EOL>

x and y are equal iff their ops and args are equal.


return hash(self.op) ^ hash(tuple(self.args))<EOL>

Need a hash method so Exprs can live in dicts.


assert is_definite_clause(sentence), "<STR_LIT>"<EOL>self.clauses.append(sentence)<EOL>


if pl_fc_entails(self.clauses, query):<EOL><INDENT>yield {}<EOL><DEDENT>


return [c for c in self.clauses<EOL>if c.op == '<STR_LIT>' and p in conjuncts(c.args[<NUM_LIT:0>])]<EOL>

Return a list of the clauses in KB that have p in their premise.
        This could be cached away for O(1) speed, but we'll recompute it.


for (lhs, rhs) in list(rules.items()):<EOL><INDENT>rules[lhs] = [alt.strip().split() for alt in rhs.split('<STR_LIT:|>')]<EOL><DEDENT>return rules<EOL>

Create a dictionary mapping symbols to alternative sequences.
    >>> Rules(A = "B C | D E")
    {'A': [['B', 'C'], ['D', 'E']]}


for (lhs, rhs) in list(rules.items()):<EOL><INDENT>rules[lhs] = [word.strip() for word in rhs.split('<STR_LIT:|>')]<EOL><DEDENT>return rules<EOL>

Create a dictionary mapping symbols to alternative words.
    >>> Lexicon(Art = "the | a | an")
    {'Art': ['the', 'a', 'an']}


import random<EOL>def rewrite(tokens, into):<EOL><INDENT>for token in tokens:<EOL><INDENT>if token in grammar.rules:<EOL><INDENT>rewrite(random.choice(grammar.rules[token]), into)<EOL><DEDENT>elif token in grammar.lexicon:<EOL><INDENT>into.append(random.choice(grammar.lexicon[token]))<EOL><DEDENT>else:<EOL><INDENT>into.append(token)<EOL><DEDENT><DEDENT>return into<EOL><DEDENT>return '<STR_LIT:U+0020>'.join(rewrite(s.split(), []))<EOL>

Replace each token in s by a random entry in grammar (recursively).
    This is useful for testing a grammar, e.g. generate_random(E_)


def __init__(self, name, rules, lexicon):

update(self, name=name, rules=rules, lexicon=lexicon)<EOL>self.categories = DefaultDict([])<EOL>for lhs in lexicon:<EOL><INDENT>for word in lexicon[lhs]:<EOL><INDENT>self.categories[word].append(lhs)<EOL><DEDENT><DEDENT>

A grammar has a set of rules and a lexicon.


return self.rules.get(cat, ())<EOL>

Return a sequence of possible rhs's that cat can be rewritten as.


return cat in self.categories[word]<EOL>


def __init__(self, grammar, trace=False):

update(self, grammar=grammar, trace=trace)<EOL>

A datastructure for parsing a string; and methods to do the parse.
        self.chart[i] holds the edges that end just before the i'th word.
        Edges are 5-element lists of [start, end, lhs, [found], [expects]].


def parses(self, words, S='<STR_LIT:S>'):

if isinstance(words, str):<EOL><INDENT>words = words.split()<EOL><DEDENT>self.parse(words, S)<EOL>return [[i, j, S, found, []]<EOL>for (i, j, lhs, found, expects) in self.chart[len(words)]<EOL>if i == <NUM_LIT:0> and lhs == S and expects == []]<EOL>

Return a list of parses; words can be a list or string.
        >>> chart = Chart(E_NP_)
        >>> chart.parses('happy man', 'NP')
        [[0, 2, 'NP', [('Adj', 'happy'), [1, 2, 'NP', [('N', 'man')], []]], []]]