Skip to content

Commit

Permalink
Merge pull request #147 from pronoiac/diagrams
Browse files Browse the repository at this point in the history
Remade diagrams
  • Loading branch information
norvig authored Mar 30, 2022
2 parents b6f85cf + 9010256 commit 7afa31e
Show file tree
Hide file tree
Showing 125 changed files with 398 additions and 134 deletions.
13 changes: 8 additions & 5 deletions docs/chapter14.md
Original file line number Diff line number Diff line change
Expand Up @@ -223,7 +223,10 @@ His problem concerned three colored blocks, but we will update it to deal with t
Suppose that a certain Eastern European country, *E*, has just decided if it will remain under communist rule or become a democracy, but we do not know the outcome of the decision.
*E* is situated between the democracy *D* and the communist country *C*:

![u14-02](images/chapter14/u14-02.jpg)
<a id="diagram-14-02"></a>
<img src="images/chapter14/diagram-14-02.svg"
onerror="this.src='images/chapter4/diagram-14-02.png'; this.onerror=null;"
alt="Diagram 14.2">

The question is: Is there a communist country next to a democracy?
Moore points out that the answer is "yes," but discovering this requires reasoning by cases.
Expand Down Expand Up @@ -529,10 +532,10 @@ To create the index, we essentially superimpose the list structure of all the ke
At each position in the tree, we create an index of the keys that have either an atom or a variable at that position.
[Figure 14.1](#f0010) shows the discrimination tree for the six keys.

| []() |
|------------------------------------------------|
| ![f14-01](images/chapter14/f14-01.jpg) |
| Figure 14.1: Discrimination Tree with Six Keys |
| <a id="fig-14-01"></a>[]() |
|---|
| <img src="images/chapter14/fig-14-01.svg" onerror="this.src='images/chapter14/fig-14-01.png'; this.onerror=null;" alt="Figure 14.1"> |
| **Figure 14.1: Discrimination Tree with Six Keys** |

Consider the query `(p ?y c)`.
Either the `p` or the `c` could be used as an index.
Expand Down
11 changes: 6 additions & 5 deletions docs/chapter16.md
Original file line number Diff line number Diff line change
Expand Up @@ -487,12 +487,13 @@ The contexts form a tree.
In our example, the `patient` context is the root of the tree, and the current patient is stored in the data base under the key `patient.` The next level of the tree is for cultures taken from the patient; the current culture is stored under the `culture` key.
Finally, there is a level for organisms found in each culture.
The current organism is stored under both the `organism` and `current-instance` keys.
The context tree is shown in [figure 16.2](#f0015).
The context tree is shown in [figure 16.2](#fig-16-02).

| []() |
|----------------------------------------|
| ![f16-02](images/chapter16/f16-02.jpg) |
| Figure 16.2: A Context Tree |

| <a id="fig-16-02"></a>[]() |
|---|
| <img src="images/chapter16/fig-16-02.svg" onerror="this.src='images/chapter16/fig-16-02.png'; this.onerror=null;" alt="Figure 16.2"> |
| **Figure 16.2: A Context Tree** |

```lisp
(defun new-instance (context)
Expand Down
118 changes: 61 additions & 57 deletions docs/chapter17.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,20 +23,21 @@ This chapter covers one small aspect of high-level vision.
## 17.1 The Line-Labeling Problem

In this chapter we look at the line-diagram labeling problem: Given a list of lines and the vertexes at which they intersect, how can we determine what the lines represent?
For example, given the nine lines in [figure 17.1](#f0010), how can we interpret the diagram as a cube?
For example, given the nine lines in [figure 17.1](#fig-17-01), how can we interpret the diagram as a cube?

| []() |
|----------------------------------------|
| ![f17-01](images/chapter17/f17-01.jpg) |
| Figure 17.1: A Cube |

| <a id="fig-17-01"></a>[]() |
|---|
| <img src="images/chapter17/fig-17-01.svg" onerror="this.src='images/chapter17/fig-17-01.png'; this.onerror=null;" alt="Figure 17.1"> |
| **Figure 17.1: A Cube** |

Before we can arrive at an interpretation, we have to agree on what the candidates are.
After all, [figure 17.1](#f0010) could be just a hexagon with three lines in the middle.
After all, [figure 17.1](#fig-17-01) could be just a hexagon with three lines in the middle.
For the purposes of this chapter, we will consider only diagrams that depict one or more *polyhedra-*three-dimensional solid figures whose surfaces are flat faces bounded by straight lines.
In addition, we will only allow *trihedral* vertexes.
That is, each vertex must be formed by the intersection of three faces, as in the corner of a cube, where the top, front, and side of the cube come together.
A third restriction on diagrams is that no so-called *accidental* vertexes are allowed.
For example, [figure 17.1](#f0010) might be a picture of three different cubes hanging in space, which just happen to line up so that the edge of one is aligned with the edge of another from our viewpoint.
For example, [figure 17.1](#fig-17-01) might be a picture of three different cubes hanging in space, which just happen to line up so that the edge of one is aligned with the edge of another from our viewpoint.
We will assume that this is not the case.

Given a diagram that fits these three restrictions, our goal is to identify each line, placing it in one of three classes:
Expand All @@ -57,24 +58,25 @@ Vertex A is the near corner of the cube, and the three lines coming out of it ar
Lines GD and DF are concave lines, indicating the junction between the cube and the surface on which it is resting.
The remaining lines are boundary lines, indicating that there is no physical connection between the cube and the background there, but that there are other sides of the cube that cannot be seen.

| []() |
|----------------------------------------|
| ![f17-02](images/chapter17/f17-02.jpg) |
| Figure 17.2: A Line-labeled Cube |

| <a id="fig-17-02"></a>[]() |
|---|
| <img src="images/chapter17/fig-17-02.svg" onerror="this.src='images/chapter17/fig-17-02.png'; this.onerror=null;" alt="Figure 17.2"> |
| **Figure 17.2: A Line-labeled Cube** |

The line-labeling technique developed in this chapter is based on a simple idea.
First we enumerate all the possible vertexes, and all the possible labelings for each vertex.
It turns out there are only four different vertex types in the trihedral polygon world.
We call them L, Y, W, and T vertexes, because of their shape.
The Y and W vertexes are also known as forks and arrows, respectively.
The vertexes are listed in [figure 17.3](#f0020).
The vertexes are listed in [figure 17.3](#fig-17-03).
Each vertex imposes some constraints on the lines that compose it.
For example, in a W vertex, the middle line can be labeled with a + or -, but not with an arrow.

| []() |
|-----------------------------------------------|
| ![f17-03](images/chapter17/f17-03.jpg) |
| Figure 17.3: The Possible Vertexes and Labels |
| <a id="fig-17-03"></a>[]() |
|---|
| <img src="images/chapter17/fig-17-03.svg" onerror="this.src='images/chapter17/fig-17-03.png'; this.onerror=null;" alt="Figure 17.3"> |
| **Figure 17.3: The Possible Vertexes and Labels** |

Each line connects two vertexes, so it must satisfy both constraints.
This suggests a simple algorithm for labeling a diagram based on constraint propagation: First, label each vertex with all the possible labelings for the vertex type.
Expand All @@ -88,17 +90,18 @@ We adjust N and V's possible labelings accordingly.
Every time we add a constraint at a vertex, we repeat the whole process for all the neighboring vertexes, to give the constraint a chance to propagate as far as possible.
When every vertex has been visited at least once and there are no more constraints to propagate, then we are done.

[Figure 17.4](#f0025) illustrates this process.
[Figure 17.4](#fig-17-04) illustrates this process.
On the left we start with a cube.
All vertexes have all possible labelings, except that we know line GD is concave (-), indicating that the cube is resting on a surface.
This constrains vertex D in such a way that line DA must be convex (+).
In the middle picture the constraint on vertex D has propagated to vertex A, and in the right-hand picture it propagates to vertex B.
Soon, the whole cube will be uniquely labeled.

| []() |
|----------------------------------------|
| ![f17-04](images/chapter17/f17-04.jpg) |
| Figure 17.4: Propagating Constraints |

| <a id="fig-17-04"></a>[]() |
|---|
| <img src="images/chapter17/fig-17-04.svg" onerror="this.src='images/chapter17/fig-17-04.png'; this.onerror=null;" alt="Figure 17.4"> |
| **Figure 17.4: Propagating Constraints** |

Many diagrams will be labeled uniquely by this constraint propagation process.
Some diagrams, however, are ambiguous.
Expand All @@ -109,7 +112,7 @@ Keep going until the diagram is either unambiguous or inconsistent.

That completes the sketch of the line-labeling algorithm.
We are now ready to implement a labeling program.
Its glossary is in [figure 17.5](#f0030).
Its glossary is in [figure 17.5](#fig-17-05).

| []() |
|-----------------------------------------------------|
Expand Down Expand Up @@ -369,12 +372,13 @@ But since there is not yet a Common Lisp standard for interacting with such devi
The macro `defdiagram` defines and names a diagram.
The name is followed by a list of vertex descriptions.
Each description is a list consisting of the name of a vertex, the vertex type (Y, A, L, or T), and the names of the neighboring vertexes.
Here again is the `defdiagram` description for the cube shown in [figure 17.6](#f0035).
Here again is the `defdiagram` description for the cube shown in [figure 17.6](#fig-17-06).

| []() |
|----------------------------------------|
| ![f17-06](images/chapter17/f17-06.jpg) |
| Figure 17.6: A Cube |
<!-- 17.6 is a copy of 17.1 -->
| <a id="fig-17-06"></a>[]() |
|---|
| <img src="images/chapter17/fig-17-01.svg" onerror="this.src='images/chapter17/fig-17-01.png'; this.onerror=null;" alt="Figure 17.6"> |
| **Figure 17.6: A Cube** |

```lisp
(defdiagram cube
Expand Down Expand Up @@ -527,14 +531,14 @@ Diagram:
```

The four interpretations correspond, respectively, to the cases where the cube is free floating, attached to the floor (GD and DF = -), attached to a wall on the right (EC and CF = -), or attached to a wall on the left (BG and BE = -).
These are shown in [figure 17.7](#f0040).
These are shown in [figure 17.7](#fig-17-07).
It would be nice if we could supply information about where the cube is attached, and see if we can get a unique interpretation.
The function ground takes a diagram and modifies it by making one or more lines be grounded lines-lines that have a concave (-) label, corresponding to a junction with the ground.

| []() |
|-----------------------------------------------|
| ![f17-07](images/chapter17/f17-07.jpg) |
| Figure 17.7: Four Interpretations of the Cube |
| <a id="fig-17-07"></a>[]() |
|---|
| <img src="images/chapter17/fig-17-07.svg" onerror="this.src='images/chapter17/fig-17-07.png'; this.onerror=null;" alt="Figure 17.7"> |
| **Figure 17.7: Four Interpretations of the Cube** |

```lisp
(defun ground (diagram vertex-a vertex-b)
Expand Down Expand Up @@ -580,17 +584,17 @@ Similarly, in programming `ground-line`, we only had to update one of the vertex
The rest is done by constraint propagation.

The next example yields the same four interpretations, in the same order (free floating, attached at bottom, attached at right, and attached at left) when interpreted ungrounded.
The grounded version yields the unique solution shown in the following output and in [figure 17.9](#f0050).
The grounded version yields the unique solution shown in the following output and in [figure 17.9](#fig-17-09).

| []() |
|----------------------------------------|
| ![f17-08](images/chapter17/f17-08.jpg) |
| Figure 17.8: Cube on a Plate |
| <a id="fig-17-08"></a>[]() |
|---|
| <img src="images/chapter17/fig-17-08.svg" onerror="this.src='images/chapter17/fig-17-08.png'; this.onerror=null;" alt="Figure 17.8"> |
| **Figure 17.8: Cube on a Plate** |

| []() |
|----------------------------------------|
| ![f17-09](images/chapter17/f17-09.jpg) |
| Figure 17.9: Labeled Cube on a Plate |
| <a id="fig-17-09"></a>[]() |
|---|
| <img src="images/chapter17/fig-17-09.svg" onerror="this.src='images/chapter17/fig-17-09.png'; this.onerror=null;" alt="Figure 17.9"> |
| **Figure 17.9: Labeled Cube on a Plate** |

```lisp
(defdiagram cube-on-plate
Expand Down Expand Up @@ -792,22 +796,22 @@ It is interesting that the same fact that makes the processing of the poiuyt tak
## 17.4 Checking Diagrams for Errors

This section considers one more example, and considers what to do when there are apparent errors in the input.
The example is taken from Charniak and McDermott's *Introduction to Artificial Intelligence*, page 138, and shown in [figure 17.12](#f0065).

| []() |
|-----------------------------------------------|
| ![f17-10](images/chapter17/f17-10.jpg) |
| Figure 17.10: An Impossible Figure (A Poiuyt) |

| []() |
|----------------------------------------|
| ![f17-11](images/chapter17/f17-11.jpg) |
| Figure 17.11: A Tower |

| []() |
| ---------------------------------------|
| ![f17-12](images/chapter17/f17-12.jpg) |
| Figure 17.12: Diagram of an arch |
The example is taken from Charniak and McDermott's *Introduction to Artificial Intelligence*, page 138, and shown in [figure 17.12](#fig-17-12).

| <a id="fig-17-10"></a>[]() |
|---|
| <img src="images/chapter17/fig-17-10.svg" onerror="this.src='images/chapter17/fig-17-10.png'; this.onerror=null;" alt="Figure 17.10"> |
| **Figure 17.10: An Impossible Figure (A Poiuyt)** |

| <a id="fig-17-11"></a>[]() |
|---|
| <img src="images/chapter17/fig-17-11.svg" onerror="this.src='images/chapter17/fig-17-11.png'; this.onerror=null;" alt="Figure 17.11"> |
| **Figure 17.11: A Tower** |

| <a id="fig-17-12"></a>[]() |
|---|
| <img src="images/chapter17/fig-17-12.svg" onerror="this.src='images/chapter17/fig-17-12.png'; this.onerror=null;" alt="Figure 17.12"> |
| **Figure 17.12: Diagram of an arch** |

```lisp
(defdiagram arch
Expand Down
49 changes: 32 additions & 17 deletions docs/chapter18.md
Original file line number Diff line number Diff line change
Expand Up @@ -53,15 +53,15 @@ Players alternate turns, except that a player who has no legal moves must pass.
When neither player has any moves, the game is over, and the player with the most pieces on the board wins.
This usually happens because there are no empty squares left, but it occasionally happens earlier in the game.

| []() |
|----------------------------------------|
| ![f18-01](images/chapter18/f18-01.jpg) |
| Figure 18.1: The Othello Board |
| <a id="fig-18-01"></a>[]() |
|---|
| <img src="images/chapter18/fig-18-01.svg" onerror="this.src='images/chapter18/fig-18-01.png'; this.onerror=null;" alt="Figure 18.1"> |
| **Figure 18.1: The Othello Board** |

| []() |
|----------------------------------------|
| ![f18-02](images/chapter18/f18-02.jpg) |
| Figure 18.2: Legal Othello Moves |
| <a id="fig-18-02"></a>[]() |
|---|
| <img src="images/chapter18/fig-18-02.svg" onerror="this.src='images/chapter18/fig-18-02.png'; this.onerror=null;" alt="Figure 18.2"> |
| **Figure 18.2: Legal Othello Moves** |

## 18.2 Representation Choices

Expand Down Expand Up @@ -487,10 +487,10 @@ Edge squares are weighted highly, corner squares higher still, and squares adjac
In general, X and C squares are to be avoided, because taking them gives the opponent a chance to take the corner.
The `weighted-squares` evaluation function reflects this.

| []() |
|----------------------------------------|
| ![f18-04](images/chapter18/f18-04.jpg) |
| Figure 18.4: Names for Edge Squares |
| <a id="fig-18-04"></a>[]() |
|---|
| <img src="images/chapter18/fig-18-04.svg" onerror="this.src='images/chapter18/fig-18-04.png'; this.onerror=null;" alt="Figure 18.4"> |
| **Figure 18.4: Names for Edge Squares** |

```lisp
(defparameter *weights*
Expand Down Expand Up @@ -537,7 +537,10 @@ By searching through several levels of moves, we can steer away from potential d

Another way to look at the `maximizer` function is as a search function that searches only one level, or *ply*, deep:

![u18-01](images/chapter18/u18-01.jpg)
<a id="diagram-18-01"></a>
<img src="images/chapter18/diagram-18-01.svg"
onerror="this.src='images/chapter18/diagram-18-01.png'; this.onerror=null;"
alt="Diagram 18.1">

The top of the tree is the current board position, and the squares below that indicate possible moves.
The `maximizer` function evaluates each of these and picks the best move, which is underlined in the diagram.
Expand All @@ -546,7 +549,10 @@ Now let's see how a 3-ply search might go.
The first step is to apply `maximizer` to the positions just above the bottom of the tree.
Suppose we get the following values:

![u18-02](images/chapter18/u18-02.jpg)
<a id="diagram-18-02"></a>
<img src="images/chapter18/diagram-18-02.svg"
onerror="this.src='images/chapter18/diagram-18-02.png'; this.onerror=null;"
alt="Diagram 4.1">

Each position is shown as having two possible legal moves, which is unrealistic but makes the diagram fit on the page.
In a real game, five to ten legal moves per position is typical.
Expand All @@ -557,11 +563,17 @@ Going up a level, it is the opponent's turn to move.
We can assume the opponent will choose the move that results in the minimal value to us, which would be the maximal value to the opponent.
Thus, the opponent's choices would be the 10- and 9-valued positions, avoiding the 20- and 23-valued positions.

![u18-03](images/chapter18/u18-03.jpg)
<a id="diagram-18-03"></a>
<img src="images/chapter18/diagram-18-03.svg"
onerror="this.src='images/chapter18/diagram-18-03.png'; this.onerror=null;"
alt="Diagram 18.3">

Now it is our turn to move again, so we apply `maximizer` once again to get the final value of the top-level position:

![u18-04](images/chapter18/u18-04.jpg)
<a id="diagram-18-04"></a>
<img src="images/chapter18/diagram-18-04.svg"
onerror="this.src='images/chapter18/diagram-18-04.png'; this.onerror=null;"
alt="Diagram 18.4">

If the opponent plays as expected, we will always follow the left branch of the tree and end up at the position with value 10.
If the opponent plays otherwise, we will end up at a position with a better value.
Expand Down Expand Up @@ -680,7 +692,10 @@ It looks at every line of play, including many improbable ones.
Fortunately, there is a way to find the optimal line of play without looking at every possible position.
Let's go back to our familiar search tree:

![u18-05](images/chapter18/u18-05.jpg)
<a id="diagram-18-05"></a>
<img src="images/chapter18/diagram-18-05.svg"
onerror="this.src='images/chapter18/diagram-18-05.png'; this.onerror=null;"
alt="Diagram 18.5">

Here we have marked certain positions with question marks.
The idea is that the whole search tree evaluates to 10 regardless of the value of the positions labeled ?<sub>*i*</sub>.
Expand Down
6 changes: 4 additions & 2 deletions docs/chapter2.md
Original file line number Diff line number Diff line change
Expand Up @@ -403,8 +403,10 @@ For example, instead of the list `(a woman took a ball)`, we want to get the nes

This corresponds to the tree that linguists draw as in figure 2.1.

![Figure 2.1: Sentence Parse Tree](images/chapter2/f02-01.jpg)
**Figure 2.1: Sentence Parse Tree**
| <a id="fig-02-01"></a>[]() |
|---|
| <img src="images/chapter2/fig-02-01.svg" onerror="this.src='images/chapter2/fig-02-01.png'; this.onerror=null;" alt="Figure 2.1"> |
| **Figure 2.1: Sentence Parse Tree** |

Using the "straightforward functions" approach we would be stuck; we'd have to rewrite every function to generate the additional structure.
With the "new notation" approach we could keep the grammar as it is and just write one new function: a version of `generate` that produces nested lists.
Expand Down
Loading

0 comments on commit 7afa31e

Please sign in to comment.