35
Two algorithms for checking emptiness

Two algorithms for checking emptiness. How to check for emptiness? Is L (A) = ; ? Need to check if there exists an accepting computation (passes through

Embed Size (px)

Citation preview

Page 1: Two algorithms for checking emptiness. How to check for emptiness? Is L (A) = ; ? Need to check if there exists an accepting computation (passes through

Two algorithms for checking emptiness

Page 2: Two algorithms for checking emptiness. How to check for emptiness? Is L (A) = ; ? Need to check if there exists an accepting computation (passes through

How to check for emptiness?

Is L(A) = ; ?Need to check if there exists an accepting computation (passes through an accepting state infinitely often).

Page 3: Two algorithms for checking emptiness. How to check for emptiness? Is L (A) = ; ? Need to check if there exists an accepting computation (passes through

Emptiness and accepting runs If there is an accepting computation, then it

contains at least one accepting state an infinite # of times.

This state must appear in a cycle. So, find a reachable accepting state on a cycle. How ?

Page 4: Two algorithms for checking emptiness. How to check for emptiness? Is L (A) = ; ? Need to check if there exists an accepting computation (passes through

Emptiness and accepting runs

There can be an exponential number of cycles in a graph!

But we want stay polynomial in the size of the graph…

Page 5: Two algorithms for checking emptiness. How to check for emptiness? Is L (A) = ; ? Need to check if there exists an accepting computation (passes through

Finding accepting runs

Rather than looking for cycles, look for SCCs: A maximal Strongly Connected Component

(SCC): a maximal set of nodes where each node is reachable from all others.

Find a reachable SCC with an accepting node.

Page 6: Two algorithms for checking emptiness. How to check for emptiness? Is L (A) = ; ? Need to check if there exists an accepting computation (passes through

Finding accepting runs

Finding SCC’s is linear in the size of the graph.

Relies on a modified DFS, in which the ‘finishing time’ (the time leaving a node) is recorded.

Let us recall DFS..

Page 7: Two algorithms for checking emptiness. How to check for emptiness? Is L (A) = ; ? Need to check if there exists an accepting computation (passes through

Depth First Search

Program DFSFor each initial state

s dfs(s)end DFS

Procedure dfs(s)for each s’ such

that R(s,s’) do

If new(s’) then dfs(s’)

end dfs.

Page 8: Two algorithms for checking emptiness. How to check for emptiness? Is L (A) = ; ? Need to check if there exists an accepting computation (passes through

Start from an initial state

q3

q4

q2

q1

q5

q1

q1

Stack:

Hash table:

1

Mark in each node:- Start time- Finish time

Page 9: Two algorithms for checking emptiness. How to check for emptiness? Is L (A) = ; ? Need to check if there exists an accepting computation (passes through

Continue with a successor

q3

q4

q2

q1

q5

q1 q2

q1

q2

Stack:

Hash table:

1

2

Mark in each node:- Start time- Finish time

Page 10: Two algorithms for checking emptiness. How to check for emptiness? Is L (A) = ; ? Need to check if there exists an accepting computation (passes through

One successor of q2.

q3

q4

q2

q1

q5

q1 q2 q4

q1

q2

q4

Stack:

Hash table:

1

2

3

Mark in each node:- Start time- Finish time

Page 11: Two algorithms for checking emptiness. How to check for emptiness? Is L (A) = ; ? Need to check if there exists an accepting computation (passes through

Backtrack to q2 (no new successors for q4).

q3

q4

q2

q1

q5

q1 q2 q4

q1

q2

Stack:

Hash table:

1

2

34

Mark in each node:- Start time- Finish time

Page 12: Two algorithms for checking emptiness. How to check for emptiness? Is L (A) = ; ? Need to check if there exists an accepting computation (passes through

Backtracked to q1

q3

q4

q2

q1

q5

q1 q2 q4

q1

Stack:

Hash table:

1

2

34

5

Mark in each node:- Start time- Finish time

Page 13: Two algorithms for checking emptiness. How to check for emptiness? Is L (A) = ; ? Need to check if there exists an accepting computation (passes through

Second successor to q1.

q3

q4

q2

q1

q5

q1 q2 q4 q3

q1

q3

Stack:

Hash table:

1

2

34

5

6

Mark in each node:- Start time- Finish time

Page 14: Two algorithms for checking emptiness. How to check for emptiness? Is L (A) = ; ? Need to check if there exists an accepting computation (passes through

Backtrack again to q1.

q3

q4

q2

q1

q5

q1 q2 q4 q3

q1

Stack:

Hash table:

1

2

34

5

6 7

8

Mark in each node:- Start time- Finish time

Page 15: Two algorithms for checking emptiness. How to check for emptiness? Is L (A) = ; ? Need to check if there exists an accepting computation (passes through

An algorithm for finding SCCs

We need the following definition for describing the algorithm:

The transpose of G, written GT, is derived from G by reversing its edges.

G GT

Page 16: Two algorithms for checking emptiness. How to check for emptiness? Is L (A) = ; ? Need to check if there exists an accepting computation (passes through

An algorithm for finding SCCs

Strongly-Connected-Components(G)

1. Call DFS(G) to compute finish[v] for each vertex in G.

2. Call Modified-DFS(GT), where the main loop of Modified-DFS(GT) processes vertices in order of decreasing finish[v].

3. Each tree in the depth-first forest of Modified-DFS(GT) is a strongly connected component of G.

Running time = running time of DFS = (V + E)

Page 17: Two algorithms for checking emptiness. How to check for emptiness? Is L (A) = ; ? Need to check if there exists an accepting computation (passes through

109

Example

1 2 34

5 6

7

8

11

12

1314

1516

Compute DFS Finishtimes

Page 18: Two algorithms for checking emptiness. How to check for emptiness? Is L (A) = ; ? Need to check if there exists an accepting computation (passes through

15

Example

6

7

1011

12

14

16

Finishtimes

Page 19: Two algorithms for checking emptiness. How to check for emptiness? Is L (A) = ; ? Need to check if there exists an accepting computation (passes through

Example

GT

15

6

7

11

1216

Swapped the direction of edges

1014

Page 20: Two algorithms for checking emptiness. How to check for emptiness? Is L (A) = ; ? Need to check if there exists an accepting computation (passes through

Example

6

7

1011

12

14

1516

GT

DFS from decreasing finish times: every tree is an SCC.

Page 21: Two algorithms for checking emptiness. How to check for emptiness? Is L (A) = ; ? Need to check if there exists an accepting computation (passes through

An alternative algorithm

The algorithm we saw so far for checking emptiness: Identify SCC’s Return “yes” if one of them contains an

accepting state

We will see a better alternative.

Page 22: Two algorithms for checking emptiness. How to check for emptiness? Is L (A) = ; ? Need to check if there exists an accepting computation (passes through

Notation

The automaton A: h , S, S0, T, Fi Denote by succ(s) the successors of

s 2 S in A.

Page 23: Two algorithms for checking emptiness. How to check for emptiness? Is L (A) = ; ? Need to check if there exists an accepting computation (passes through

The Double DFS algorithm

The first DFS finds a state f 2 F The second DFS attempts to close a

loop around it.

The trick is: how to avoid exploring the entire graph for each accepting state ?

dfs1

dfs2

Page 24: Two algorithms for checking emptiness. How to check for emptiness? Is L (A) = ; ? Need to check if there exists an accepting computation (passes through

The Double-DFS algorithm

DFS1(s) { push(s,Stack1); hash(s,Table1); for each t 2 Succ (s) {if t Table1 then

DFS1(t);} if s 2 F then DFS2(s); pop(Stack1); }

DFS2(s) { push(s, Stack2); hash(s, Table2) ; for each t 2 Succ (s) do { if t is on Stack1 exit(“not

empty”); else if t Table2 then DFS2(t)

} pop( Stack2); }

Upon finding an accepting cycle, Stack1, Stack2, t, determines a witness: an accepting cycle reached from an initial state.

Page 25: Two algorithms for checking emptiness. How to check for emptiness? Is L (A) = ; ? Need to check if there exists an accepting computation (passes through

The Double DFS algorithm (full version)

procedure Main() { foreach s 2 S_0 { if s Table1 then DFS1(s);

} output(“empty”); exit;} procedure DFS1(s) { push(s,Stack1); hash(s,Table1); foreach t 2 Succ (s) { if t Table1 then

DFS1(t); } if s 2 F then DFS2(s); pop(Stack1); }

procedure DFS2(s){ push(s, Stack2); hash(s, Table2) ; for each t 2 Succ (s) do { if t is on Stack1 exit(“not

empty”); else if t Table2 then DFS2(t)

} pop(Stack2);}

Input: AInitialize: Stack1:={} , Stack2:={} Table1:={} , Table2:={}

Page 26: Two algorithms for checking emptiness. How to check for emptiness? Is L (A) = ; ? Need to check if there exists an accepting computation (passes through

dfs1

1 2 3 4

8

5 6 7

Stack 1 = {1 – 6}Table 1 = {1 – 6}

The Double DFS algorithm

Page 27: Two algorithms for checking emptiness. How to check for emptiness? Is L (A) = ; ? Need to check if there exists an accepting computation (passes through

dfs1

1 2 3 4

8

5 6 7

Stack 1 = {1 – 7}Table 1 = {1 – 7}

The Double DFS algorithm

Page 28: Two algorithms for checking emptiness. How to check for emptiness? Is L (A) = ; ? Need to check if there exists an accepting computation (passes through

dfs1

1 2 3 4

8

5 6 7

Stack 1 = {1 – 6}Table 1 = {1 – 7}

For the first time we identified an accepting state for which all the successors were already explored. Now it’s DFS2’s turn to try to close the loop.

The Double DFS algorithm

Page 29: Two algorithms for checking emptiness. How to check for emptiness? Is L (A) = ; ? Need to check if there exists an accepting computation (passes through

dfs2

1 2 3 4

8

5 6 7

Stack 1 = {1 – 6} Stack 2 = {7}Table 1 = {1 – 7} Table 2 = {7}

The Double DFS algorithm

Page 30: Two algorithms for checking emptiness. How to check for emptiness? Is L (A) = ; ? Need to check if there exists an accepting computation (passes through

dfs1

1 2 3 4

8

5 6 7

Stack 1 = {1 – 4} Stack 2 = {}Table 1 = {1 – 7} Table 2 = {7}

Still has successors…

The Double DFS algorithm

Page 31: Two algorithms for checking emptiness. How to check for emptiness? Is L (A) = ; ? Need to check if there exists an accepting computation (passes through

dfs1

1 2 3 4

8

5 6 7

Stack 1 = {1 – 4,8} Stack 2 = {}Table 1 = {1 – 8} Table 2 = {7}

The Double DFS algorithm

Page 32: Two algorithms for checking emptiness. How to check for emptiness? Is L (A) = ; ? Need to check if there exists an accepting computation (passes through

dfs1

1 2 3 4

8

5 6 7

Stack 1 = {1 – 4} Stack 2 = {}Table 1 = {1 – 8} Table 2 = {7}

Again we identified a bad state for which all successors were already explored. Now it’s DFS’2 turn to try to close the loop.

The Double DFS algorithm

Page 33: Two algorithms for checking emptiness. How to check for emptiness? Is L (A) = ; ? Need to check if there exists an accepting computation (passes through

dfs2

1 2 3 4

8

5 6 7

Stack 1 = {1 – 4} Stack 2 = {5 - 6}Table 1 = {1 – 8} Table 2 = {5 - 7}

No point continuing to what is already in Table 2 (why?)

The Double DFS algorithm

Page 34: Two algorithms for checking emptiness. How to check for emptiness? Is L (A) = ; ? Need to check if there exists an accepting computation (passes through

The Double DFS algorithm

dfs2

1 2 3 4

8

5 6 7

Stack 1 = {1 – 4} Stack 2 = {8}Table 1 = {1 – 8} Table 2 = {5 – 8}

Bingo! Found a cycle !(DFS2 progresses to node 3 which is on Stack1 but not in Table 2)

Page 35: Two algorithms for checking emptiness. How to check for emptiness? Is L (A) = ; ? Need to check if there exists an accepting computation (passes through

The Double-DFS algorithm outputs “empty” iff L(A) = ;.

If it outputs “not empty”, then content of Stack1 + Stack2 + t defines an accepted (looping) word.

The algorithm runs in (worst-case) time and space: O(|A|).

Theorems about the D-DFS algorithm