# Solutions to Second Midterm Exam

### Directions:

• Answer the problems on the exam pages.
• There are five problems, some with multiple parts, for 100 total points plus 10 extra credit. Actual scale A = 93, C = 63.
• Some useful definitions precede the questions below.
• No books, notes, calculators, or collaboration.
• In case of a numerical answer, an arithmetic expression like "217 - 4" need not be reduced to a single integer.

Question text is in black, solutions in blue.

```  Q1: 10 points
Q2: 15 points
Q3: 15+10 points
Q4: 30 points
Q5: 30 points
Total: 100+10 points
```

Definitions and Other Notes:

N is the set of naturals, {0, 1, 2, 3,...}.

Question 3 uses an inductively defined function from {a, b}* to N. We define f(λ) = 0, and for any string w we define f(wa) = f(w) + 1 and f(wb) = 2f(w).

Question 4 uses the following inductive definition of "set expression":

1. An atomic set expression has a value that is a set of `int` values.
2. If E and F are set expressions, so are E ∪ F, E ∩ F, and E-bar, denoting the union of E and F, the intersection of E and F, and the complement of E respectively.
3. Nothing else is a set expression.

Question 4 assumes that we have defined a real-Java class `IntSet` whose objects are sets of `int` values. The only method of this class that you will need is `public boolean isIn (int x)`, which returns `true` if and only if the `int` value `x` is in the calling set. Note that Question 4 will ask you to write a different method `isIn`, for the `SetExpression` class.

We also have the following real-Java class for set expressions:

``````public class SetExpression {
public static final int UNION = 1;
public static final int INTERSECTION = 2;
public static final int COMPLEMENT = 3;
boolean isLeaf;
IntSet leafValue;
SetExpression left, right;
int op;

// usual constructors, getters, and setters
``````

Question 5 uses the following labeled undirected graph:

``````  [a] ---1--- [s] ---1--- [f]
|           |           |
3           6           9
|           |           |
[b] ---1--- [d] ---1--- [g]
|           |           |
3           6           9
|           |           |
[c] ---1--- [e] ---1--- [h]
``````

• Question 1 (10): Identify each of the following five concepts, giving enough detail to make it clear that you are familiar with them (2 points each):

• (a, 2) the Fibonacci numbers

The Fibonacci numbers are a sequence of natural numbers defined by the rules F(0) = 0, F(1) = 1, and for any n with n ≥ 1, F(n+1) = F(n) + F(n-1). The sequence begins 0, 1, 1, 2, 3, 5, 8, 13,...

• (b, 2) the one's complement of a binary string

The one's complement of a binary string w is another binary string of the same length as w, with a 0 wherever w has a 1 and a 1 wherever w has a 0. For example, the one's complement of 01001 is 10110.

• (c, 2) an undirected cycle in an undirected graph

An undirected cycle in an undirected graph is a path from some node x to itself that never reuses an edge. It must have three or more edges. (I insisted on a definition that ruled out paths from some x to some y and then back along the same route, for example.)

• (d, 2) a heuristic for an A search

A heuristic for an A* search is a function that assigns each node x of the graph a non-negative real number, which is a lower bound on the best-path distance from x to a goal node. It is used to determine the order in which entries come off of the priority queue. (I insisted on your saying that h(x) was between 0 and d(x, g).)

• (e, 2) a bipartite graph

A bipartite graph is one whose nodes can be partitioned into two sets, such that every edge has one endpoint in each set. Equivalently, it is an undirected graph with no cycles of odd length. Also equivalently, it is a graph whose nodes may be two-colored so that no edge connects nodes of the same color.

• Question 2 (15): Let R be a binary relation on some set A and assume that R is transitive. By the definition of transitivity, if R(x, y) and R(y, z) are true, then R(x, z) must be true. Suppose that x1, x2,..., xk are any k elements of A, and that we know that R(xi, xi+1) is true for every i with i ≤ i < k. Prove that R(x1, xk) is true. (Hint: Use ordinary induction, with a base case of k = 3.)

Ordinary induction on k, starting with k = 3, where P(k) is the statement "R(x1, xk)".

Base Case: We want to prove R(x1, x3). We know R(x1, x2) and R(x2, x3) from the assumptions. So R(x1, x3) follows by transitivity.

Inductive Hypothesis: R(x1, xk)

Inductive Step: We want to prove P(k+1) which is R(x1, xk+1). We have R(x1, xk) from the IH and R(xk, xk+1) from the assumptions. So our desired statement follows by transitivity.

• Question 3 (15+10): This question uses the function f from {a, b}* to N defined above.

• (a, 5) Evaluate f(aabb), f(baba), and f(abba).

f(aabb) = 2f(aab) = 2(2f(aa)) = 4(f(a) + 1) = 4(f(λ) + 1 + 1) = 4(0 + 2) = 8.

f(baba) = f(bab) + 1 = 2f(ba) + 1 = 2(f(b) + 1) + 1 = 2(2f(λ) + 1) + 1 = 2(1) + 1 = 3.

f(abba) = f(abb) + 1 = 2f(ab) + 1 = 2(2f(a)) + 1 = 2(2(f(λ) + 1)) + 1 = 4(1) + 1 = 5.

• (b, 10) Prove by induction on all naturals n that there exists a string w such that f(w) = n.

Ordinary induction on all naturals. P(n) is "∃w:f(w) = n".

Base case: n = 0. We must prove that some string w exists with f(w) = 0. The definition tells us that λ is such a string.

Inductive Hypothesis: ∃w: f(w) = n

Inductive Step: We must prove ∃v:f(v) = n + 1. Using the IH, we have w such that f(w) = n. Letting v = wa, the definition tells us that f(v) = f(wa) = f(w) + 1 = n + 1.

• (c, 10) Prove that for any natural n, there exists a string w such that (1) w never has two a's in a row, and (2) f(w) = n. (Hint: Use strong induction on all naturals n. If you know that f(w) = n, how can you get strings whose f values are 2n and 2n + 1?

Strong induction on all naturals. P(n) is "&exists;w: w satisfies (1) and (2)". We define Q(n) to be "∀i: (i ≤n) → P(i)".

Base case: Let w = λ, then w does not have two a's in a row and f(w) = 0.

Strong inductive hypothesis: For any i with i ≤ n, there exists a string w such that w does not have two a's in a row and f(w) = i.

Inductive step: We must prove that there exists a string v such that v does not have two a's in a row and f(v) = n + 1.

Case 1: n + 1 is odd. Let k = n/2 so that n + 1 = 2k + 1. By the SIH, let w be a string without two a's in a row such that f(w) = k. Then let v = wba, so that f(v) = 2f(w) + 1 = 2k + 1. We know that v does not have two a's in a row because w doesn't, and the new a is separated from any other a's.

Case 2: n + 1 is even. Let k = (n + 1)/2, so that 2k = n + 1. By the SIH, let w be a string with no two a's in a row such that f(w) = k. Then let v = wb, so that f(v) = 2f(w) = 2k = n + 1. We know that v does not have two a's in a row because w doesn't and v has no new a's.

• Question 4 (30): This question uses the definition of set expressions and the Java classes `IntSet` and `SetExpression`, all defined above.

• (a, 5) If A denotes the set {2, 3, 7}, B denotes the set {3, 6, 7}, and C denotes the set {2, 7, 9}, what set is denoted by the set expression A ∩ (B ∪ C-bar)?

C-bar is the set of all ints except 2, 7, and 9. B ∪ C-bar is the set of all ints except 2 and 9. (Many of you interpreted ∪ as intersection here for some reason.) Then A ∩ (B ∪ C-bar) = {3, 7} as only 2 fails to be in the other set.

• (b, 15) Write a real-Java method ```public boolean isIn (int x)``` for the `SetExpression` class. It should return `true` if and only if the `int` value `x` is in the set denoted by the calling `SetExpression` object.

``````
public boolean isIn (int x) {
if (isLeaf) return leafValue.isIn(x);
if (op = UNION) return left.isIn(x) || right.isIn(x);
if (op = INTERSECTION) return left.isIn(x) && right.isIn(x);
else return !left.isIn(x);}
``````

This assumes that the input is correctly formed, with `op` equal to one of the three given values, and that the argument of a COMPLEMENT operation is stored in `left`. Many of you confused the int value x with leafValue (which is a set, not an int) or with the op values (which are ints only because I learned Java before the invention of the enum feature).

• (c, 10) Prove by induction on all set expressions E that your method returns the correct result when called on E. Note that to prove somethgin about your method, your answer has better refer to the code of your method!

Induction on all set expressions E, where P(E) says "Our method returns a boolean that tells whether x is in the set denoted by E".

Base case: E is a leaf, containing an `IntSet` object in its leaf value. We call the `isIn` method of the `IntSet` class, which we assume returns a boolean telling whether x is in the set.

Inductive hypothesis: P(F) and P(G) are true for any set expressions F and G we combine with an operation to get E.

Inductive step: We must prove P(E), and there are three cases depending on the `op` value for E. If op = UNION, we recursively determine whether x is in the sets for F or G, and by the IH these calls give correct answers. Then we return true if and only if at least one of these calls return true. If op = INTERSECTION, we make the same recursive calls and return true if and only if both of them return true. Finally, if op = COMPLEMENT, we reach the else clause of the code, compute whether x is in the set for F by a recursive call (which returns a correct answer by the IH), and return the negation of this answer. In each case our output matches the intended meaning of the operator.

• Question 5 (30): This question uses the undirected graph G pictured above. In every one of these searches, (1) when two or more nodes go into the open list at the same time, they come out in alphabetical order, and (2) a closed list is used so that the search can recognize nodes that have already been processed, according to the respective types of search. Each search has start node s and goal node g.

• (a, 10) Trace the depth-first search from s and draw the DFS tree, stopping when g has been found. Ignore the edge labels.

The stack starts with s. We process s and push its neighbors, making the stack {a, d, f} starting from the top. We pop a and push its only neighbor b, getting {b, d, f}. We pop b and push its neighbors c and d, getting {c, d, d, f}. (We don't push a because it is on the closed list, but d is not on the closed list.) We next pop c and push its neighbor e to get {e, d, d, f}. We pop e and push its neighbors d and h to get {d, h, d, d, f}. We pop d and push g, getting {g, h, d, d, f}. We pop g and declare victory.

The DFS tree is a single path s-a-b-c-e-d-g. The edges from s to d and from s to f are not on the tree as we never closed the corresponding node entries -- they remained on the stack at the end.

• (b, 10) Trace the breadth-first search from s and draw the BFS tree, stopping when G has been found. Ignore the edge labels.

The queue starts with s. We dequeue s and enqueue a, d, and f to get {a, d, f}. We dequeue a and enqueue b to get {d, f, b}. We dequeue d and enqueue e and g to get {f, b, e, g}. We dequeue f and enqueue g to get {b, e, g, g}. We dequeue b and enqueue c to get {e, g, g, c}. We dequeue e and enqueue h to get {g, g, c, h}. Finally we dequeue g and declare victory.

The path we found is s-d-g because we found d from s and g from d. The BFS tree contains only the nodes that we dequeued: s is the root and has children a, d, and f; a has only child b, d has children e and g (with a non-tree edge to b), and f has no children.

• (c, 10) Perform a uniform-cost search of the graph from s, using the edge labels, and stopping when the algorithm may conclude that it has found the best-path distance from s to g.

We begin with (s,0) on the priority queue. We dequeue (s, 0) and enqueue (a,1), (d,6), and (f,1). We dequeue (a,1) (using the alphabetical tie-breaker) and enqueue (b,4). We dequeue (f,1) and enqueue (g,10). The queue now holds (b,4), (d,6), and (g,10). We dequeue (b,4) and enqueue (c,7) and (d,5). We dequeue (d,5) and enqueue (e,11) and (g,6). We next might dequeue either (d,6) or (g,6), since these two nodes were not enqueued at the same time so the tie-breaker does not apply. If we dequeue (d,6) we just discard it as d is on the closed list. Once we dequeue (g,6) we declare victory, finding the path s-a-b-d-g of length 6.