Cse321, Programming Languages and Compilers Lecture #4, Jan. 24, 2007 • Homework 3 • Representing sets as lists • the cross product of two.

Download Report

Transcript Cse321, Programming Languages and Compilers Lecture #4, Jan. 24, 2007 • Homework 3 • Representing sets as lists • the cross product of two.

Cse321, Programming Languages and Compilers
Lecture #4, Jan. 24, 2007
• Homework 3
• Representing sets as lists
• the cross product of two sets
• epsilon transitions
• epsilon - closure
•Interpreting an NFA
•NFA to DFA
Labs scheduled:
11/7/2015
Thursday 4:00 pm,
Friday at 9:00 am
1
Cse321, Programming Languages and Compilers
Assignments
• Read Chapter 2, pages 27-72
– There will be a 5 minute quiz next lecture
• Programming exercise 4 is listed on the web page. It
is due next Monday.
– exercise writing accumulating parameter functions
– a guided exercise to write the e-closure in 10 easy steps
11/7/2015
2
Cse321, Programming Languages and Compilers
Homework 3
fun reverse [] = []
| reverse (x::xs) = reverse xs @ [x];
fun reverse2 xs =
let fun revonto [] ans = ans
| revonto (x::xs) ans = revonto xs (x::ans)
in revonto xs [] end;
fun count n [] = 0
| count n (x::xs) =
if n=x then 1 + count n xs else count n xs;
fun concatenate [] = []
| concatenate (xs::xss) = xs @ concatenate xss;
11/7/2015
3
Cse321, Programming Languages and Compilers
Fully Parenthesized
fun
|
|
|
|
and
toStr Empty = "#"
toStr (C c) = implode [c]
toStr (Concat(x,y)) = toStrP x ^ toStrP y
toStr (Union(x,y)) = toStrP x ^"+"^toStrP y
toStr (Star x) = toStrP x ^ "*"
toStrP x = "("^toStr x^")";
- toStr re1;
val it = "((+)+((-)+(#)))((D)((D)*))" : string
11/7/2015
4
Cse321, Programming Languages and Compilers
Not parenthesizing leaf REs
fun
|
|
|
|
and
|
|
toStr2 Empty = "#"
toStr2 (C c) = implode [c]
toStr2 (Concat(x,y)) = toStr2P x ^ toStr2P y
toStr2 (Union(x,y)) = toStr2P x ^"+"^toStr2P y
toStr2 (Star x) = toStr2P x ^ "*"
toStr2P (x as (C _)) = toStr2 x
toStr2P (x as Empty) = toStr2 x
toStr2P x = "("^toStr2 x^")";
- toStr2 re1;
val it = "(++(-+#))(D(D*))" : string
11/7/2015
5
Cse321, Programming Languages and Compilers
Escaping special characters
fun
|
|
|
|
escape
escape
escape
escape
escape
#"+" = "\\+"
#"*" = "\\*"
#"(" = "\\("
#")" = "\\)"
c = implode [c];
fun
|
|
|
|
and
|
|
toStr3 Empty = "#"
toStr3 (C c) = escape c
toStr3 (Concat(x,y)) = toStr3P x ^ toStr3P y
toStr3 (Union(x,y)) = toStr3P x ^"+"^toStr3P y
toStr3 (Star x) = toStr3P x ^ "*"
toStr3P (x as (C _)) = toStr3 x
toStr3P (x as Empty) = toStr3 x
toStr3P x = "("^toStr3 x^")";
- toStr3 re1;
val it = "(\\++(-+#))(D(D*))" : string
11/7/2015
6
Cse321, Programming Languages and Compilers
A separate rule for each sub-RE
fun
|
|
|
|
and
|
|
|
|
and
|
|
|
and
|
|
toStr4
toStr4
toStr4
toStr4
toStr4
toStrC
toStrC
toStrC
toStrC
toStrC
toStrU
toStrU
toStrU
toStrU
toStrS
toStrS
toStrS
Empty = "#"
(C c) = escape c
(Concat(x,y)) = toStrC x ^ toStrC y
(Union(x,y)) = toStrU x ^"+"^toStrU y
(Star x) = toStrS x ^ "*"
(x as (C _)) = toStr4 x
(x as Empty) = toStr4 x
(x as (Concat _)) = toStr4 x
(x as (Star _)) = toStr4 x
x = "("^toStr4 x^")"
(x as (C _)) = toStr4 x
(x as Empty) = toStr4 x
(x as (Union _)) = toStr4 x
x = "("^toStr4 x^")"
(x as (C _)) = toStr4 x
(x as Empty) = toStr4 x
x = "("^toStr4 x^")";
- toStr4 re1;
val it = "(\\++-+#)DD*" : string
11/7/2015
7
Cse321, Programming Languages and Compilers
Representing Sets in ML
• We do it for ‘int’ others would be similar
• Key – Represent a set as an ordered list without duplicates
fun mem x [] = false
| mem x (y::ys) =
if x=y then true
else mem x ys;
datatype order
= EQUAL
| LESS
| GREATER;
fun setAdd x [] = [x]
Note the use of the Int library
compare function.
| setAdd x (y::ys) =
case Int.compare (x,y) of
EQUAL => (y::ys)
| LESS => x::y::ys
| GREATER => y :: setAdd x ys;
11/7/2015
8
Cse321, Programming Languages and Compilers
Union of two sets
• Take advantage of the fact that the lists are ordered, this allows
union with time proportional to what?
fun
|
|
|
setUnion [] [] = []
setUnion [] ys = ys
setUnion xs [] = xs
setUnion (x::xs) (y::ys) =
case Int.compare (x,y) of
EQUAL => setUnion xs (y::ys)
| LESS => x:: setUnion xs (y::ys)
| GREATER => y :: setUnion (x::xs) ys;
fun setConcat [] = []
| setConcat (x::xs) = setUnion x (setConcat xs);
11/7/2015
9
Cse321, Programming Languages and Compilers
Can we turn a normal list into a set?
(* Turn a list into a set
*)
(* sort and remove duplicates. *)
fun sort [] = []
| sort (x::xs) = setAdd x (sort xs);
fun remDupFromOrdered [] = []
| remDupFromOrdered [x] = [x]
| remDupFromOrdered (x::y::zs) =
if x=y then remDupFromOrdered (y::zs)
else x:: remDupFromOrdered (y::zs);
fun norm xs = remDupFromOrdered(sort xs);
11/7/2015
10
Cse321, Programming Languages and Compilers
Cross Product
• Consider the two sets
– [1,2,6]
– [3,5]
• The cross product is a set of pairs
– all possible pairs (x,y) where x comes from [1,2,6] and y comes from [3,5]
– [(1,3),(1,5),(2,3),(2,5),(6,3),(6,5)]
• How could we compute this? In pseudo code
( ans := [ ]
; while not (null xs) do
let val x = hd xs
val ptr = y
in while not (null ptr) do
let val y = hd ptr
in ans := (x,y)::ans
ptr := tl ptr
end;
xs := tl xs
end)
11/7/2015
This has the
pattern of a nested
set of
accumulating
parameter
functions!
11
Cse321, Programming Languages and Compilers
ML code
fun innerWhile x [] ans = ans
| innerWhile x (y::ys) ans =
innerWhile x ys ((x,y)::ans) ;
fun outerWhile ys [] ans = ans
| outerWhile ys (x::xs) ans =
outerWhile ys xs (innerWhile x ys ans);
fun cross xs ys = outerWhile ys xs [];
11/7/2015
( ans := [ ]
; while not (null xs) do
let val x = hd xs
in while not (null ys) do
let val y = hd ys
in ans := (x,y)::ans
xs := tl xs
ys := tl ys
end
end)
12
Cse321, Programming Languages and Compilers
The power of a set of strings
if A = [“x”, “y”]
what is AA, or AAA, or AAAA
fun power 0 x = [""]
| power n x =
map (op ^) (cross x (power (n-1) x));
power 3 ["a","xy"];
Val it = ["xyaxy","xyaa","xyxyxy","xyxya“
,"aaxy","aaa","axyxy","axya"]
11/7/2015
13
Cse321, Programming Languages and Compilers
Concat(Union(C #”+”,Union(C #”-”,Empty))
,Concat(C #”D”,Star (C #”D”)))
(+|-| ε)DD*
ε
+
0
1
ε
8
val ex6 =
ε
(8,15,
ε
[Edge (9,Epsilon,10)
6
,Edge (8,Epsilon,0)
,Edge (8,Epsilon,6)
ε
,Edge (1,Epsilon,9)
,Edge (7,Epsilon,9)
,Edge (0,Char #"+",1)
,Edge (6,Epsilon,2)
,Edge (6,Epsilon,4)
,Edge (3,Epsilon,7)
,Edge (5,Epsilon,7)
,Edge (2,Char #"-",3)
,Edge (4,Epsilon,5)
,Edge (11,Epsilon,14)
,Edge (10,Char #"D",11)
,Edge (14,Epsilon,12)
,Edge (13,Epsilon,15)
,Edge (14,Epsilon,15)
,Edge (15,Epsilon,14)
,Edge (12,Char #"D",13)]) : Nfa
11/7/2015
2
4
-
ε
9
3
ε
ε
ε
10
D
7
11
5
ε
14
ε
12
ε
D
13
ε
15
14
ε
Cse321, Programming Languages and Compilers
Epsilon transitions
+
0
ε
1
ε
8
ε
ε
2
-
9
3
6
ε
4
ε
ε
ε
7
11
ε
14
ε
12
ε
D
13
– eclosure [8] = {0,6,2,4,5,7,9,10}
11/7/2015
10
D
5
• Note that in state 8, one can get to
{0,6,2,4,5,7,9,10} by not consuming
any characters.
• We need only take epsilon transitions
• This set is called the epsilon-closure
• How do we compute this?
ε
ε
15
15
ε
Cse321, Programming Languages and Compilers
1-step epsilon
+
0
ε
1
ε
8
ε
ε
2
-
9
3
6
ε
4
ε
ε
ε
10
D
7
11
5
• Note that every state has a 1-step
epsilon set.
many states
have empty
• oneStep 8 = [0,6]
epsilon sets
• oneStep 0 = [ ]
• oneStep 4 = [5]
• oneStep 6 = [2,4]
• ...
11/7/2015
ε
ε
14
ε
12
ε
D
13
ε
15
16
ε
Cse321, Programming Languages and Compilers
Recall how an NFA is represented
val ex6 =
(8,15,
[Edge (9,Epsilon,10)
,Edge (8,Epsilon,0)
,Edge (8,Epsilon,6)
,Edge (1,Epsilon,9)
,Edge (7,Epsilon,9)
,Edge (0,Char #"+",1)
,Edge (6,Epsilon,2)
,Edge (6,Epsilon,4)
,Edge (3,Epsilon,7)
,Edge (5,Epsilon,7)
,Edge (2,Char #"-",3)
,Edge (4,Epsilon,5)
,Edge (11,Epsilon,14)
,Edge (10,Char #"D",11)
,Edge (14,Epsilon,12)
,Edge (13,Epsilon,15)
,Edge (14,Epsilon,15)
,Edge (15,Epsilon,14)
,Edge (12,Char #"D",13)])
11/7/2015
fun oneStep n (Edge(s,Epsilon,f)) =
if n=s then [f] else []
| oneStep n (Edge(s,Char _,f)) = []
• Given a list of edges we apply
this function to every edge.
fun oneStepFromEdges es n =
setConcat(map (oneStep n) es);
• How does this work?
17
Cse321, Programming Languages and Compilers
Step – by - step
val edges =
[Edge (9,Epsilon,10)
,Edge (8,Epsilon,0)
,Edge (8,Epsilon,6)
,Edge (1,Epsilon,9)
,Edge (7,Epsilon,9)
,Edge (0,Char #"+",1)
,Edge (6,Epsilon,2)
,Edge (6,Epsilon,4)]
- oneStep 8 (Edge(5,Epsilon,6));
val it = [ ]
- oneStep 8 (Edge(8,Epsilon,6));
val it = [6]
we only get output if
the start state
matches n
fun oneStepFromEdges n es =
List.concat
(map (oneStep n) es);
- map (oneStep 8) edges;
val it = [[],[0],[6],[],[],[],[],[]]
- setConcat [[],[0],[6],[],[],[],[],[]];
val it = [0,6] : int list
11/7/2015
18
Cse321, Programming Languages and Compilers
One step from a set of states
• Note oneStepFromEdge only gives the e-states from
a single starting state.
• What if I wanted all the reachable states on epsilon
from both 8 or 9?
10
D
+
0
ε
1
ε
ε
ε
8
ε
ε
2
-
6
ε
4
ε
14
9
3
ε
ε
ε
11
7
ε
5
12
D
13
ε
fun oneStepFromSet es states =
setConcat (map (oneStepFromEdges es) states); 15
11/7/2015
19
ε
Cse321, Programming Languages and Compilers
Iterate
fun oneStepFromSet es states =
setConcat (map (oneStepFromEdges es) states);
- oneStepFromSet edges [8];
val it = [0,6] : int list
- oneStepFromSet edges (setUnion [8] [0,6]);
val it = [0,2,4,6] : int list
- oneStepFromSet edges (setUnion [0,6,8] [0,2,4,6]);
val it = [0,2,4,5,6] : int list
- oneStepFromSet edges (setUnion [0,2,4,6,8] [0,2,4,5,6]);
val it = [0,2,4,5,6,7] : int list
- oneStepFromSet edges (setUnion [0,2,4,5,6,8] [0,2,4,5,6,7]);
val it = [0,2,4,5,6,7,9] : int list
- oneStepFromSet edges (setUnion [0,2,4,5,6,7,8] [0,2,4,5,6,7,9]);
val it = [0,2,4,5,6,7,9,10] : int list
- oneStepFromSet edges (setUnion [0,2,4,5,6,7,8,9] [0,2,4,5,6,7,9,10]);
val it = [0,2,4,5,6,7,9,10] : int list
11/7/2015
20
Cse321, Programming Languages and Compilers
eclose
fun eclose edges states =
let val new = oneStepFromSet edges states
val union = setUnion new states
in if union = states
then states
else ( print (setToString states)
; print (setToString new)
; print (setToString union)
; print "-------------\n"
; eclose edges union )
end;
11/7/2015
- eclose edges [8];
[8]
[0,6]
[0,6,8]
----------------------[0,6,8]
[0,2,4,6]
[0,2,4,6,8]
----------------------[0,2,4,6,8]
[0,2,4,5,6]
[0,2,4,5,6,8]
----------------------[0,2,4,5,6,8]
[0,2,4,5,6,7]
[0,2,4,5,6,7,8]
----------------------[0,2,4,5,6,7,8]
[0,2,4,5,6,7,9]
[0,2,4,5,6,7,8,9]
----------------------[0,2,4,5,6,7,8,9]
[0,2,4,5,6,7,9,10]
[0,2,4,5,6,7,8,9,10]
----------------------val it = [0,2,4,5,6,7,8,9,10]
21
Cse321, Programming Languages and Compilers
Fixed-point functions
fun fix f init =
let val new = f init
in if new=init then new else fix f new end;
fun eclose2 edges xs =
let fun step x = setUnion x (oneStepFromSet edges x)
in fix step xs end;
- eclose2 edges [8];
val it = [0,2,4,5,6,7,8,9,10] : int list
11/7/2015
22
Cse321, Programming Languages and Compilers
Simulating an NFA
ε
0
ε
ε
1
ε
2
a
3
ε
6
4
b
ε
5
ε
ε
7
a
8
b
9
b
10
• Given
a string, say “ababb” use the NFA to
determine if the NFA “accepts” the string.
•ε -closure , All those states reachable from a given
set on transitions via ε transitions only
•Initial state is ε-closure of {0}
•For character in the input string keep track of what
set-of-states the machine could possibly be in.
11/7/2015
23
Cse321, Programming Languages and Compilers
Example: “ababb”
ε
0
ε
ε
1
ε
2
a
3
ε
6
4
state
b
ε
5
ε
ε
input
7
a
8
b
9
“ababb”
C := nextchar();
{3,8;6,7,0,1,2,4}
“babb”
while C <> eof do
{9,5;6,7,0,1,2,4}
“abb”
{ S := move(S,C);
{3,8;6,7,0,1,2,4}
“bb”
{9,5;6,7,0,1,2,4}
“b”
};
{10,5;6,7,0,1,2,4}
““
if S is in F
10, so the string is accepted.
11/7/2015
10
Accepting Algorithm
S := S0;
{0;1,2,4,7}
Final state includes the accepting state,
b
C := nextchar()
then return “yes”
else return “no”
24
Cse321, Programming Languages and Compilers
fun transitionOn c states edges =
let fun good (Edge(s,Char x,f)) =
(c=x) andalso (mem s states)
| good _ = false
fun finish (Edge(s,_,f)) = f
in map finish (List.filter good edges) end;
fun nfa edges final states [] = mem final states
| nfa edges final states (c::cs) =
let val _ = print ("State = "^setToString states)
val _ = print ("Input = "^implode(c::cs)^"\n")
val new = eclose2 edges
(transitionOn c states edges)
val _ = print ("On '"^implode [c]^
"' we can get to "^
setToString new)
in if new = []
then false
else nfa edges final new cs
end;
11/7/2015
25
Cse321, Programming Languages and Compilers
Code
fun accept (start,final,edges) input =
nfa edges final
(eclose2 edges [start])
(explode input)
- accept ex6 "+DDD";
State = [0,2,4,5,6,7,8,9,10]
Input = +DDD
On '+' we can get to [1,9,10]
State = [1,9,10]
Input = DDD
On 'D' we can get to [11,12,14,15]
State = [11,12,14,15]
Input = DD
On 'D' we can get to [12,13,14,15]
State = [12,13,14,15]
Input = D
On 'D' we can get to [12,13,14,15]
val it = true : bool
11/7/2015
26
Cse321, Programming Languages and Compilers
A failing examples
- accept ex6 "+DaD“;
State = [0,2,4,5,6,7,8,9,10]
Input = +DaD
On '+' we can get to [1,9,10]
State = [1,9,10]
Input = DaD
On 'D' we can get to [11,12,14,15]
State = [11,12,14,15]
Input = aD
On 'a' we can get to []
val it = false : bool
- accept ex6 "+";
State = [0,2,4,5,6,7,8,9,10]
Input = +
On '+' we can get to [1,9,10]
val it = false : bool
11/7/2015
27
Cse321, Programming Languages and Compilers
Making a DFA
ε
0
ε
ε
1
a
2
3
ε
ε
6
ε
b
4
ε
5
ε
7
a
8
b
9
b
10
To turn an NFA into a DFA Simulate all possible
transitions simultaneously. Algorithm is a famous one
and is called “the subset construction”.
DStates := { (e-clos(S0),unmarked) };
while exists (T,unmarked) in DStates do
{ mark T;
for-each
input symbol
{ U
a
do
:= e-clos(move(T,a));
if U is not in DStates
then
add (U,unmarked) to Dstates
Dtran[T,a] := U
11/7/2015
}
}
28
Cse321, Programming Languages and Compilers
ε
0
ε
ε
1
ε
2
a
3
ε
6
4
b
ε
5
ε
ε
7
a
8
b
9
b
10
• Initial state is 0
• ε –closure of 0 is {0;1,2,4,7}
• From any of {0;1,2,4,7}
– We can make a transition on “a” to {3,8}
– We can make a transition on “b” to {5}
• ε –closure of {3,8} is {3,8;6,7,0,1,2,4}
• ε –closure of {5} is {5;6,7,0,1,2,4}
• From any of {3,8;6,7,0,1,2,4}
– We can make a transition on “a” to {3,8} -- which we’ve seen before
– We can make a transition on “b” to {9,5} -- which is new
• From any of {4;6,7,0,1,2,4}
– We can make a transition on “a” to {3,8} -- which we’ve seen before
– We can make a transition on “b” to {5} – which we’ve seen before
ε –closure of {9,5} is {9;6,7,0,1,2,4}
• From any of {9;6,7,0,1,2,4}
– We can make a transition on “a” to {3,8} -- which we’ve seen before
– We can make a transition on “b” to {10,5} – which is new
11/7/2015
29
Cse321, Programming Languages and Compilers
Example Algorithm use
ε
0
ε
ε
1
ε
a
2
3
ε
6
b
4
ε
ε
ε
5
Dstates
a
7
8
Dtran on a
b
9
b
10
Dtran on b
A{0;1,2,4,7}
B {3,8;1,2,4,6,7}
C{5;1,2,4,6,7}
B{1,2,3,4,6,7,8}
B{3,8;1,2,4,6,7}
D{5,9;6,7,1,2,4}
C{1,2,4,5,6,7}
B{3,8;1,2,4,6,7}
C{5;1,2,4,6,7}
D{1,2,4,5,6,7,9}
B{3,8;1,2,4,6,7}
E{5,10;1,2,4,6,7}
E{1,2,4,5,6,7,10} B{3,8;1,2,4,6,7}
C{5;1,2,4,6,7}
b
C
b
b
A
a
B
a
11/7/2015
b
D
b
E
a
a
30