COMP5001 Artificial Intelligence · Week 3 notes

Heuristics and Logic

Searching smarter with a good guess, then writing knowledge in logic and checking what follows

Sections 1 to 6 (heuristics) and 8 to 15 (logic) are adapted from the lecture notes of CS50’s Introduction to Artificial Intelligence with Python by Brian Yu and David J. Malan (Harvard University), licensed under CC BY-NC-SA 4.0. Sections 7 and 16 were written for COMP5001. The notes are shared under the same licence.

This week

By the end of the week you should be able to:

Remember Week 1? You solved the knights and knaves puzzles by trying each possibility. Section 14 does the same by model checking, the way a computer would.

  1. Where Week 2 left off
  2. A heuristic is a guess
  3. Greedy best-first search
  4. Where greedy goes wrong
  5. A* search
  6. A good guess never overestimates
  7. What is logic?
  8. Knowledge-based agents
  9. Symbols, and joining sentences: not, and, or
  10. If … then, and if and only if
  11. Models and knowledge bases
  12. Entailment
  13. Model checking
  14. Knights and knaves, by model checking
  15. In the code: logic.py and harry.py
  16. Heuristics and logic in the real world
  17. Check yourself, key terms and reading

1Where Week 2 left off

Last week, breadth-first search explored 29 squares of the Week 1 maze to find the 17-step path, and depth-first search explored 25. When you solved the same maze yourself in Week 1, you did not look at every square. You could see where B was, so you headed towards it.

DFS and BFS cannot do that. They try squares in a fixed order (newest first, or oldest first), whatever the maze looks like. This week’s first half gives the search a sense of direction.

Uninformed and informed search

Uninformed search uses no knowledge about where the goal is. DFS and BFS are uninformed.

Informed search uses extra knowledge about the problem, such as a guess at how far each state is from the goal, to look in the right direction first.

2A heuristic is a guess

To head towards B, the search needs a number for each square that says roughly how far it is from B. In a maze, the simplest such number is the Manhattan distance: count how many rows and how many columns the square is from B, and add them up. It ignores the walls. (The name comes from walking between blocks in Manhattan, where you cannot cut diagonally across.)

C D h = 12h = 6 87432197511087643211751110876412109865 really 10 A B
Figure 1. The Week 1 maze. The grey number in each square is its Manhattan distance to B. C and D are the two squares compared on the slide. The purple band is the real route from D to B.

Worked example

Heuristic

A heuristic h(n) is a quick estimate of the cost from state n to the goal. In a maze we use the Manhattan distance.

Key idea

A heuristic is a guess. It is quick to work out and usually points the right way, but it can be wrong. Manhattan distance ignores walls, so it can be too low, but it is never too high (Section 6 explains why that matters).

3Greedy best-first search

Greedy best-first search uses the loop from Week 2 and changes one line: which node comes out of the frontier. Instead of the newest (DFS) or the oldest (BFS), it takes the node with the smallest h, the one that looks closest to the goal.

frontier = a node with the initial state explored = an empty set repeat: if the frontier is empty: there is no solution remove the node with the smallest h(n) from the frontier if the node is a goal: return the solution add the node to explored expand the node: add each neighbour to the frontier unless it is already in the frontier or explored

If two nodes have the same h (a tie), we take the one that joined the frontier first. Your own code may break ties differently, so your numbers can differ slightly.

Worked example: greedy on the Week 1 maze

The small number in the corner of each square is h. Lilac squares have been taken out of the frontier, numbered in order; dashed squares are waiting; the ringed square was taken out last.

6 7 8 5 9 4 10 3 2 8 7 6 4 3 2 1 9 7 5 1 10 8 7 6 4 3 2 11 7 5 12 11 10 8 7 6 4 12 10 9 8 6 5 12 11 7 A B
After step 10. From A, up and right both had h = 12: a tie, so greedy took up (it joined the frontier first), and the same at step 3. It went up the left side and along the top to D (step 8, h = 6). The wall blocks the way, so it goes down: h rises to 7, then 8. The only other squares waiting have h = 11 and 12, so these still win.
6 7 8 14 15 16 17 5 9 13 4 10 11 12 3 2 8 7 6 4 3 2 1 9 7 5 1 10 8 7 6 4 3 2 11 7 5 12 11 10 8 7 6 4 12 10 9 8 6 5 12 11 7 A B
Finished (step 18). Greedy explored only 18 squares (BFS: 29, DFS: 25) and found the 17-step path, the shortest. Every explored square is on the path.
7 = h, the guess of steps to Bwaiting in the frontierexplored (step number)path

Here the guess was good, so greedy went almost straight to B. Is it always this good? No.

4Where greedy goes wrong

The maze below is maze4.txt in week02-search/maze. Look at it before reading on: which way would you go from A? Most people go down and along the long bottom corridor, because they can see it leads straight to the right-hand side.

9 8 2 3 4 5 6 7 6 5 4 3 2 1 7 1 8 7 6 5 4 2 5 3 11 10 9 8 7 6 4 13 5 14 13 12 11 10 9 8 7 6 13 5 A B
After step 9. At step 2, right had h = 11 and down had h = 13, so greedy went right. It reaches the corner with h = 4: B looks close, but a wall is in the way.
15 16 17 18 19 20 14 13 12 11 10 9 8 2 3 4 5 6 7 6 5 4 3 2 1 7 1 8 7 6 5 4 2 5 3 11 10 9 8 7 6 4 13 5 14 13 12 11 10 9 8 7 6 13 A B
Finished (step 21). The route turned back to the left and h rose to 8, but the only other square waiting (below A) had h = 13, so greedy kept going. Its path is 20 steps.
7 = h, the guess of steps to Bwaiting in the frontierexplored (step number)path

The shortest path goes down and along the bottom: 16 steps. Greedy never found it, because at step 2 the bottom route looked worse (13 against 11), and after that the top route always looked better than the square below A.

Key idea

Greedy best-first search only looks forward, at the guess to go. It never counts the steps it has already taken, so a misleading guess can lead it a long way round.

5A* search

A* search (said “A star”) fixes greedy’s mistake by adding the cost already paid. For each node it adds two numbers:

A* search

Take the frontier node with the smallest f(n) = g(n) + h(n): the cost so far plus the guessed cost to go. In other words, the estimated length of the whole path through n.

Worked example: two squares in the frontier

X Y 6 5 4 3 2 1 7 1 8 7 6 5 4 2 5 3 11 10 9 8 7 6 4 13 5 14 13 12 11 10 9 8 7 6 A B
Figure 2. The trap maze. X (on the top route) and Y (on the bottom route) are both waiting in the frontier. The bands show how each was reached from A.
XY
h(n): guess to B711
g(n): steps from A so far115
f(n) = g(n) + h(n)1816

Greedy compares only h and takes X (7 is less than 11). A* sees that X is already 11 steps from A, so a path through X is about 18 steps long, while a path through Y is about 16. It takes Y.

Worked example: A* on the trap maze

In these pictures the big number in each explored square is its f, not the step number. Ties are broken by taking the square nearer B (smaller h).

14 12 12 12 12 12 12 12 12 14 6 5 4 3 2 1 7 1 8 7 6 5 4 2 5 3 11 10 9 8 7 6 4 13 5 14 13 12 11 10 9 8 7 6 16 16 A B
After step 11. Along the top route f stays at 12: each step adds 1 to g and takes 1 off h. Round the corner f jumps to 14, so A* also tries the square below A, which has f = 1 + 13 = 14.
16 16 14 12 16 12 16 12 12 12 12 12 12 16 14 16 16 16 16 16 16 16 16 16 16 6 5 4 3 2 1 7 1 8 7 6 5 4 2 5 3 11 10 9 8 7 6 4 13 5 14 13 12 11 10 9 8 7 6 18 A B
Finished (step 27). The top route’s next square has f = 18; every square on the bottom route has f = 16. A* follows the bottom route and finds the 16-step path, the shortest.
7 = h, the guess of steps to Bwaiting in the frontierexplored (number = f)path
Squares explored / path lengthDFSBFSGreedyA*
Week 1 maze25 / 2129 / 1718 / 1721 / 17
maze2.txt194 / 3077 / 3054 / 3050 / 30
maze3.txt17 / 166 / 45 / 45 / 4
maze4.txt (the trap)21 / 2032 / 1621 / 2027 / 16

Greedy often explores the fewest squares, but on the trap maze its path is 4 steps too long. BFS and A* found the shortest path in every maze, and A* always explored fewer squares than BFS, because the heuristic keeps it away from squares that lead the wrong way.

Worked example: A* with real costs

In Week 2, BFS on the road map returned the 55-minute route via Andover, because it counts roads, not minutes. A* uses the minutes. Here g is the driving time so far, and h is a straight-line estimate of the time still to go (it can never be more than the real time, because no road is shorter than a straight line).

25 20 25 30 30 35 Winchester Andover Stockbridge Romsey Salisbury Driving times in minutes (made-up but realistic). h = 45h = 28h = 25h = 30h = 0
Figure 3. The Week 2 road map, with driving times in minutes on the roads and an estimate h for each town.
StepTake outAdd to the frontier (g + h = f)Frontier after
1Winchester (f = 0 + 45)Andover 25 + 28 = 53; Stockbridge 20 + 25 = 45; Romsey 25 + 30 = 55Stockbridge 45, Andover 53, Romsey 55
2Stockbridge (45)Salisbury 50 + 0 = 50Salisbury 50, Andover 53, Romsey 55
3Salisbury (50)goal ✓ via Stockbridge: 50 minutes

A* returns the optimal 50-minute route, and it never even expanded Andover or Romsey. Note that the goal test happens when a node is taken out of the frontier, not when it is added: that is what lets A* compare every way of reaching the goal before it stops.

6A good guess never overestimates

A straight line between two towns can never be longer than the road between them, because the road can bend but the straight line cannot. So a straight-line heuristic never guesses too high. Manhattan distance in a maze is the same: walls can only make the real route longer, never shorter.

Admissible heuristic

A heuristic that never overestimates the true cost to the goal. A* with an admissible heuristic always finds the shortest path.

What if the guess is too high?

Go back to Figure 2 and suppose the heuristic wrongly said that Y was 30 steps from B. Then f(Y) = 5 + 30 = 35. A* would reach B along the top route (f = 20) before it ever took Y, and it would return the 20-step path. An overestimate can make the best route look worse than it is, so A* skips it.

Other heuristics, and where they come from

Manhattan distance is the right guess for a maze, but every problem needs its own heuristic. Table 1 collects some common ones.

ProblemHeuristic h(n)Never overestimates?
Maze: up, down, left, rightManhattan distance: rows apart + columns apart.Yes: walls only make the route longer.
Maze where diagonal moves are allowedThe larger of rows apart and columns apart. A diagonal step covers one of each.Yes. Manhattan distance would not be: it can be up to twice the real number of steps.
Road map, sat-navStraight-line distance, as the crow flies. For a time estimate, the time to drive that line at top speed.Yes: no road is shorter than a straight line.
Sliding-tile puzzle (the 8-puzzle)The number of tiles out of place. Better: the sum of each tile’s Manhattan distance from its home square.Yes: every tile out of place needs at least one move, in fact at least its Manhattan distance.
Any problemh = 0: no guess at all.Yes, but it gives no help: A* becomes BFS (question 4 in Check yourself).
Any problem2 × Manhattan distance, or any guess that is inflated to speed things up.No. A* may then return a longer path (seminar Activity 3).

Table 1. Some heuristics, and whether each one is admissible.

Relax the problem

The reliable way to invent an admissible heuristic: drop a rule so that the problem becomes easier, then use the exact cost of the easier problem as the guess. With no walls, a maze costs exactly the Manhattan distance. If you could drive anywhere, a journey costs exactly the straight-line distance. If tiles could jump straight home, the 8-puzzle costs exactly the number of tiles out of place. An easier problem can never cost more than the real one, so the guess never overestimates.

Two more rules of thumb. A guess that is closer to the truth makes A* explore fewer squares: on the 8-puzzle, the tiles-out-of-place guess and the Manhattan-distance guess are both admissible, but the second is nearer the real answer and solves the puzzle far faster. And if you have two admissible heuristics, take the larger of the two at each node: it is still admissible, and at least as good as either on its own. Next week, planning uses a guess of the same kind: the number of goal facts that are not yet true.

Going further: CS50 and Russell & Norvig also describe consistent heuristics, which never drop by more than the cost of one step. Manhattan distance and straight-line distance are both consistent. You do not need this for COMP5001.

7What is logic?

The second half of the week is about logic. In Week 1 you solved the knights and knaves puzzles by reasoning: “if A is a knight, then …”. This half shows how to write that kind of knowledge down precisely, and how a computer can then work out what follows from it.

SentenceTrue or false?
Winchester is in Hampshire.true
2 + 2 = 5.false
Close the door!neither: an order
Is it raining?neither: a question
It is raining.true or false, depending on the day

Statement and logic

A statement is a sentence that is either true or false. “2 + 2 = 5” is a statement: it is false, but it is still true-or-false. Orders and questions are not statements.

Logic is a precise way to write statements, with rules for working out what follows from them. It is the language of the symbolic AI you met in Week 1.

Compare the last two rows. “Is it raining?” and “It is raining” use almost the same words, but only the second is a statement. Whether it is true depends on which world we are in: on a wet day it is true, on a dry day it is false. That idea, that the same sentence can be true in one world and false in another, is at the heart of this half of the week.

8Knowledge-based agents

People reason from what they already know to reach new conclusions. CS50 starts with an example from Harry Potter. Suppose we know three things:

  1. If it didn’t rain, Harry visited Hagrid today.
  2. Harry visited Hagrid or Dumbledore today, but not both.
  3. Harry visited Dumbledore today.

Did it rain today? None of the three sentences says so, but we can work it out. Sentence 3 says Harry visited Dumbledore, and sentence 2 says he did not visit both, so:

  1. Harry did not visit Hagrid today.

Now sentence 1 says that if it had not rained, Harry would have visited Hagrid. Sentence 4 says he did not. So:

  1. It rained today.

Knowledge-based agent, sentence and inference

A knowledge-based agent stores what it knows as sentences, and reasons with them to reach new conclusions.

A sentence is a statement written in a logic. CS50, the textbooks and the code all say “sentence”, so from here on we do too.

Inference is working out new sentences from old ones, as we did for sentences 4 and 5.

We reached sentence 5 by being clever: we picked the right sentences in the right order. A computer needs a method that works without cleverness. The rest of the week builds one: first a precise way to write the sentences (Sections 9 and 10), then a way to check what follows (Sections 11 to 13).

9Symbols, and joining sentences: not, and, or

Symbols

Writing out “Harry visited Hagrid today” every time is slow, so we give each statement a short name:

Propositional symbol

A short name for one statement. In any world, it is either true or false. Textbooks often use single capital letters: P, Q, R.

A symbol does not say whether its statement is true. It only names the statement. Whether rain is true depends on the world we are in.

Most sentences are built from smaller ones. Sentence 1, “If it didn’t rain, Harry visited Hagrid today”, contains two statements, “it rained” (with a “not”) and “Harry visited Hagrid”, joined by “if … then”. Propositional logic is logic built from symbols joined by five small words, called connectives: not, and, or, if … then, and if and only if. This section covers the first three, and Section 10 the other two.

Not, and, or

Read ¬ as “not”, ∧ as “and” and ∨ as “or”. Each connective has a simple rule for when the whole sentence is true:

Here P and Q stand for any two sentences. A table that lists every combination of true and false, and the value of a sentence in each, is called a truth table.

PQ¬PP ∧ QP ∨ Q
falsefalsetruefalsefalse
falsetruetruefalsetrue
truefalsefalsefalsetrue
truetruefalsetruetrue

Table 2. Truth table for not, and, or. Each row is one possible combination of values for P and Q.

“Or” means at least one

In logic, P ∨ Q is true when P is true, or Q is true, or both (the last row of Table 2). Everyday English is not always like this: “for dessert you can have cookies or ice cream” usually means one but not both. That is called an exclusive or. To say “but not both” in logic, add ¬(P ∧ Q).

Worked example: sentence 2 in symbols

“Harry visited Hagrid or Dumbledore today, but not both” has two parts. “Hagrid or Dumbledore” is hagrid ∨ dumbledore. “Not both” is ¬(hagrid ∧ dumbledore). Both parts must be true, so join them with “and”:

(hagrid ∨ dumbledore) ∧ ¬(hagrid ∧ dumbledore)

The brackets matter, as in arithmetic: ¬(hagrid ∧ dumbledore) means “not both”, while ¬hagrid ∧ dumbledore means “not Hagrid, and Dumbledore”.

10If … then, and if and only if

Read rain → indoors as “rain implies indoors”, and rain ↔ indoors as “rain if and only if indoors”. CS50 calls these two connectives implication and biconditional.

If … then

Think of rain → indoors as a promise: “If it is raining, I am indoors.” When is the promise broken?

The last case surprises most people. If the “if” part is false, the whole “if … then” sentence is true, whatever the “then” part says. Logically, we learn nothing from rain → indoors on a dry day.

PQP → QP ↔ Q
falsefalsetruetrue
falsetruetruefalse
truefalsefalsefalse
truetruetruetrue

Table 3. Truth table for if … then (→) and if and only if (↔).

If and only if

P ↔ Q is an “if … then” in both directions: P → Q and Q → P. “I am indoors if and only if it is raining” says that rain means indoors, and also that indoors means rain. So on a dry day I am outside. P ↔ Q is true exactly when P and Q have the same value.

Key idea

P → Q is false only when P is true and Q is false. P ↔ Q is true when P and Q are the same.

Table 4 collects all five connectives.

ConnectiveSymbolExampleTrue when
not¬¬PP is false
and∧P ∧ Qboth are true
or∨P ∨ Qat least one is true
if … then (implication)→P → QP is false, or Q is true
if and only if (biconditional)↔P ↔ QP and Q have the same value

Table 4. The five connectives of propositional logic.

Worked example: the Harry knowledge in symbols

Sentence 1, “If it didn’t rain, Harry visited Hagrid today”, becomes ¬rain → hagrid. With sentence 2 from Section 9 split into its two parts, everything we know is:

  1. ¬rain → hagrid
  2. hagrid ∨ dumbledore
  3. ¬(hagrid ∧ dumbledore)
  4. dumbledore

These four sentences are the knowledge base used in Section 13 and in harry.py.

11Models and knowledge bases

Whether a sentence is true depends on the world. With two symbols, rain and hagrid, there are four possible worlds: both true, only rain true, only hagrid true, or both false.

Model

One possible world: a true or false value for every symbol. For example, {rain = true, hagrid = false} is a model: it rained, and Harry did not visit Hagrid.

Each symbol can be true or false, so every new symbol doubles the number of possible worlds. With n symbols there are 2 × 2 × … × 2 = 2n models.

SymbolsModels (worlds)
24
38
416
101,024
20about 1 million
30about 1 billion

Table 5. The number of models doubles with every symbol.

Is a sentence true in a model?

To find out, put the model’s values into the sentence and work from the inside out, using the rules in Table 4.

Worked example: one sentence in one model

Is ¬rain → hagrid true in the model {rain = false, hagrid = false}?

  1. rain is false, so ¬rain is true.
  2. hagrid is false.
  3. true → false is false (the third row of Table 3).

So the sentence is false in this model: on a dry day when Harry did not visit Hagrid, sentence 1 is broken.

Knowledge base (KB)

The set of sentences an agent knows to be true. The KB is true in a model only when every sentence in it is true, so it behaves like one big sentence joined by ∧.

Knowledge rules worlds out. Suppose the KB is a single sentence, rain ∨ hagrid. It is false only in the world where both symbols are false, so that world is ruled out, and three are left. Every sentence we add can only rule out more worlds, never bring one back.

12Entailment

If “It is a Tuesday in January” is true, must “It is January” be true? Yes: every world in which it is a Tuesday in January is a world in which it is January. The other way round fails: on a Wednesday in January, “It is January” is true but “It is a Tuesday in January” is not. One world like that is enough to show that the second sentence does not follow from the first.

All worlds It is January It is a Tuesday in January a Wednesday in January
Figure 4. Every world where it is a Tuesday in January (green) is inside the worlds where it is January (purple). The red dot is a world where “It is January” is true but “It is a Tuesday in January” is false.

Entailment

A entails B when B is true in every world where A is true. We also say that B follows from A. It is written A ⊨ B, read “A entails B”.

For a knowledge-based agent the question is always the same: does the knowledge base entail the sentence we want to know about, the query? In symbols, KB ⊨ query? For the Harry example: does our knowledge base entail rain?

Entailment is not the same as “if … then”

The arrow → is a connective: it is a word inside a sentence, and the sentence it makes can be true in some worlds and false in others. Entailment ⊨ is not part of any sentence. It is a claim about sentences: in every world where the first is true, the second is true too.

13Model checking

Entailment says “B is true in every world where the KB is true”. The most direct way to check that is to look at every world. That is model checking.

to check whether KB ⊨ query: for each model (every true/false choice of the symbols): if the KB is true in this model: if the query is false in this model: return “no” return “yes”

Models where the KB is false are skipped: they are worlds that contradict what we know, so they do not matter. If the query is true in every model that is left, the KB entails it.

Worked example: did it rain?

The knowledge base is the four sentences at the end of Section 10, and the query is rain. There are three symbols, so 23 = 8 models (Table 6). Take the sentences one at a time and rule out the models where each one is false:

One model is left: rain true, hagrid false, dumbledore true. rain is true in it, so it is true in every model where the KB is true: KB ⊨ rain. It rained, the same answer as in Section 8, but this time found without any cleverness.

rainhagriddumbledoreKB true?
falsefalsefalseno: breaks 4
falsefalsetrueno: breaks 1 (no rain, so Hagrid)
falsetruefalseno: breaks 4
falsetruetrueno: breaks 3 (not both)
truefalsefalseno: breaks 4
truefalsetrueyes
truetruefalseno: breaks 4
truetruetrueno: breaks 3 (not both)

Table 6. Model checking the Harry knowledge base. Crossed-out models break at least one sentence; the green model is the only one where the KB is true.

The same table answers other queries too. Does the KB entail ¬hagrid? In the one model left, hagrid is false, so yes: Harry did not visit Hagrid. Does the KB entail hagrid? No: the one model left is a counter-example.

The catch

Model checking always gives the right answer, but it looks at every model, and the number of models doubles with every symbol (Table 5). Three symbols is easy. A real knowledge base with hundreds of symbols has more models than there are atoms in the universe. Next week starts here: ways to reason that do not check every world.

14Knights and knaves, by model checking

“We are both knaves.” … A B
Figure 5. The Week 1 puzzle: every person is a knight (always tells the truth) or a knave (always lies). A says “We are both knaves.” B says nothing.

In Week 1 you solved this puzzle in words. Most people reason like this: “Suppose A is a knight. Then what A said is true, so A is a knave. But A cannot be both, so A is not a knight. So A is a knave, which means A was lying: they are not both knaves. A is a knave, so B must be the one who is not. B is a knight.” That is good reasoning, but it needs a clever idea (“suppose A is a knight”) and a different clever idea for every new puzzle. A computer needs a method with no cleverness in it. This section builds one in four steps, and the steps work for any knights-and-knaves puzzle.

Step 1: name the statements

A statement is anything that is true or false. Here there are four, one for each thing a person might be. Give each a short name, a propositional symbol:

A symbol does not say whether its statement is true. It just names it. In one world AKnight is true; in another it is false. Our job is to find the world that fits everything we know.

Step 2: write down the rules of the island

The puzzle says every person is a knight or a knave. We also know nobody is both. In plain words, for A: “A is a knight or a knave, and not both.” In symbols:

(AKnight ∨ AKnave) ∧ ¬(AKnight ∧ AKnave)

Read it as: (A is a knight or A is a knave) and it is not the case that (A is a knight and A is a knave). The first bracket rules out “neither”; the second rules out “both”. Write the same sentence for B. Together these are sentence 1 of the knowledge base.

Step 3: write down what A said

A said: “We are both knaves.” As a sentence of logic that is simply AKnave ∧ BKnave. But we cannot add it to the knowledge base as it stands, because we do not know whether A was telling the truth. What we do know is the rule about who tells the truth:

This is the one trick in the whole method: never write down a person’s statement on its own. Write “if knight, then it is true” and “if knave, then it is false”. The second sentence uses a “not” in front of the statement: ¬(both knaves) means “at least one of them is not a knave”. B said nothing, so there is nothing to write for B.

Those three sentences are the whole knowledge base. Nothing in it says what A or B is; the answer has to follow from it.

Step 4: check every world

Four symbols give 24 = 16 worlds, but sentence 1 throws out every world where someone is both or neither. Only four worlds survive it: each of A and B is a knight or a knave. Now test sentences 2 and 3 in each of the four. The question to ask in each world is: is what A said true here, and is that what A’s kind allows?

A is aB is a“Both knaves” isSentence 2 (knight → true)Sentence 3 (knave → false)Fits?
knightknightfalsebroken: A is a knight but said something falseholds: A is not a knave, so it says nothingno
knightknavefalsebroken: the sameholdsno
knaveknightfalseholds: A is not a knight, so it says nothingholds: A is a knave and said something falseyes
knaveknavetrueholdsbroken: A is a knave but said something trueno

Table 7. The four worlds left after sentence 1, tested against sentences 2 and 3. Only one fits the whole knowledge base.

Two things in the table deserve a second look. First, an “if … then” sentence holds whenever its “if” part is false: in the third row A is not a knight, so sentence 2 is not tested and cannot be broken. That is the “promise not tested” rule from Section 10, and it is what lets one sentence sit quietly while the other does the work. Second, the last row is the one people find surprising: two knaves looks consistent with “we are both knaves”, until you remember that a knave cannot say something true.

Reading off the answer

Only one world fits: A is a knave and B is a knight. Every sentence we care about is true in every surviving world (there is only one), so the knowledge base entails AKnave and it entails BKnight: KB ⊨ AKnave ∧ BKnight. This is the same answer as Week 1, found with no cleverness: name the statements, write the rules, check every world. If two worlds had survived, the puzzle would have two answers; if none had, the puzzle would contradict itself.

Recipe for any knights-and-knaves puzzle

1. Two symbols per person, XKnight and XKnave. 2. For each person, the island rule: one kind, not both. 3. For each statement S that a person X makes, two sentences: XKnight → S and XKnave → ¬S. 4. Check every world and keep the ones where every sentence is true. The seminar sheet uses the recipe on Week 1’s harder puzzle, where B speaks too, and on a new one; CS50’s Knights project writes the same puzzles in logic.py, which is next.

15In the code: logic.py and harry.py

The practical uses CS50’s logic.py (folder week04-knowledge/logic in the module code). It gives a Python class for each part of propositional logic: Symbol, Not, And, Or, Implication and Biconditional, plus the function model_check. Here is harry.py, the Harry example:

from logic import *

rain = Symbol("rain")
hagrid = Symbol("hagrid")
dumbledore = Symbol("dumbledore")

knowledge = And(
    Implication(Not(rain), hagrid),
    Or(hagrid, dumbledore),
    Not(And(hagrid, dumbledore)),
    dumbledore
)

print(model_check(knowledge, rain))

The four lines inside And(…) are the four sentences from Section 10, in the same order. And joins them into one knowledge base, true only when all four are. The last line asks whether the knowledge base entails rain, and prints True.

How model_check works

model_check does exactly what Section 13 describes, but it builds the models one symbol at a time. Its helper, check_all, takes the list of symbols that have no value yet:

A function that calls itself like this is called recursive. Each call fixes one more symbol, so with three symbols it reaches all 8 complete models, the rows of Table 6. Each sentence class has an evaluate(model) method that works out whether the sentence is true in a model, using the rules in Table 4.

Try it in the practical

16Heuristics and logic in the real world

A question to think about: a railway signalling system has been checked by model checking, and in every world that fits its knowledge base no two trains share a track. Can we trust it completely? The check is only as good as the knowledge base. A missing or wrong sentence, or something the symbols do not cover (a broken sensor, a driver who ignores a signal), is outside the proof. People who understand the railway must check the sentences, and the system still needs testing in the real world.

Check yourself

Try these without looking back. The answers are at the end.

  1. In Figure 1, what is h for the square directly below D? Is the real number of steps from that square to B more or less than h?
  2. The frontier holds three squares with h = 9, 4 and 6, and g = 2, 10 and 6. Which one does greedy best-first search take next? Which one does A* take?
  3. In maze4.txt, why does greedy best-first search find a 20-step path when a 16-step path exists?
  4. Suppose h = 0 for every square. Does it ever overestimate? What would A* do then?
  5. A robot in a grid can also move diagonally, one square at a time. Is Manhattan distance still admissible? Suggest a heuristic that is.
  6. Which of these are statements? “Winchester is in Scotland.” “Shut the window!” “Is the robot holding a block?”
  7. Let P be “It is sunny” and Q be “We go to the beach”. Write in symbols: (a) “It is not sunny.” (b) “If it is sunny, we go to the beach.” (c) “We go to the beach if and only if it is sunny.”
  8. P is false and Q is true. Which of these are true? P ∧ Q, P ∨ Q, P → Q, Q → P, P ↔ Q.
  9. How many models are there with 4 symbols? With 10?
  10. Does rain ∨ hagrid entail rain? Give a model that shows why or why not.
  11. CS50’s example. P: “It is a Tuesday.” Q: “It is raining.” R: “Harry will go for a run.” The KB is (P ∧ ¬Q) → R, P and ¬Q. Use model checking to decide whether KB ⊨ R.
  12. The first Week 1 knights and knaves puzzle: A says “I am both a knight and a knave.” Using the symbols AKnight and AKnave, write the knowledge base and check the four models. What is A?

Key terms

Uninformed / informed searchUses no knowledge of where the goal is (DFS, BFS) / uses a heuristic to look in the right direction.
Heuristic, h(n)A quick estimate of the cost from n to the goal.
Manhattan distanceRows apart + columns apart, ignoring walls.
Greedy best-first searchTakes the frontier node with the smallest h; fast, but the path may not be the shortest.
g(n)The cost from the start to n (steps so far).
A* searchTakes the frontier node with the smallest g(n) + h(n).
Admissible heuristicNever overestimates; with it, A* finds the shortest path.
Relaxed problemThe problem with a rule dropped. Its exact cost is an admissible heuristic for the real problem.
StatementA sentence that is either true or false.
LogicA precise way to write statements, with rules for working out what follows.
Knowledge-based agentAn agent that stores what it knows as sentences and reasons with them.
SentenceA statement written in a logic.
InferenceWorking out new sentences from old ones.
Propositional symbolA short name for one statement, such as rain or P.
Connectivesnot (¬), and (∧), or (∨), if … then (→), if and only if (↔).
Truth tableA table of every combination of true and false, with the value of a sentence in each.
ModelOne possible world: a true or false value for every symbol. n symbols give 2n models.
Knowledge base (KB)The sentences an agent knows to be true.
Entailment, A ⊨ BB is true in every model where A is true: B follows from A.
QueryThe sentence we want to know about: does the KB entail it?
Model checkingChecking KB ⊨ query by looking at every model.

Reading and next week

Next week: Knowledge and Planning. Model checking doubles its work with every symbol. Next week starts with ways to reason that do not check every world (inference rules, and a first look at first-order logic), then uses facts and actions to plan, and solves the Week 1 river crossing.

Answers to Check yourself

  1. The square below D is 1 row and 6 columns from B, so h = 7. The real route goes down, along and back up round the wall: 9 steps, which is more than h. Manhattan distance can be too low, never too high.
  2. Greedy takes the square with h = 4 (the smallest h). A* works out f = g + h: 2 + 9 = 11, 10 + 4 = 14 and 6 + 6 = 12, so it takes the square with h = 9 (f = 11). The square that looks closest has already cost 10 steps to reach.
  3. At step 2 the square to the right of A has h = 11 and the square below has h = 13, so greedy goes right. From then on, every square on the top route has a smaller h than the square below A, so greedy never goes back. It only looks at h and never counts the steps already taken.
  4. No: 0 is never more than the real distance, so h = 0 is admissible, and A* still finds the shortest path. But f = g + 0, so A* just takes the square with the fewest steps so far. In a maze that is the same as BFS: no sense of direction at all.
  5. No. A diagonal step moves one row and one column at once. A square 3 rows and 3 columns away is 3 steps, but Manhattan distance says 6: an overestimate, so A* might miss the shortest path. Use the larger of rows apart and columns apart (3 here). It never overestimates, because every step changes a row or a column by at most one.
  6. “Winchester is in Scotland” is a statement (a false one). “Shut the window!” is an order and “Is the robot holding a block?” is a question, so neither is a statement.
  7. (a) ¬P (b) P → Q (c) Q ↔ P, which is the same as P ↔ Q.
  8. P ∧ Q is false (P is false). P ∨ Q is true (Q is true). P → Q is true (the “if” part is false). Q → P is false (Q is true and P is false: the only way to break an “if … then”). P ↔ Q is false (they differ).
  9. 24 = 16, and 210 = 1,024.
  10. No. In the model {rain = false, hagrid = true}, rain ∨ hagrid is true but rain is false. One such model is enough to show that rain does not follow.
  11. There are 8 models. P must be true, which rules out the 4 models where P is false. Q must be false, which rules out 2 more. That leaves P true, Q false, with R true or R false. With P true and Q false, P ∧ ¬Q is true, so (P ∧ ¬Q) → R is false when R is false: that model goes too. One model is left, and R is true in it, so KB ⊨ R: Harry will go for a run.
  12. KB: (AKnight ∨ AKnave) ∧ ¬(AKnight ∧ AKnave), AKnight → (AKnight ∧ AKnave) and AKnave → ¬(AKnight ∧ AKnave). Both true: breaks the first sentence. Both false: breaks the first sentence. Knight only: the second sentence needs A to be a knave as well, so it is false. Knave only: the third sentence is ¬(false ∧ true) = true, so this model fits. A is a knave.