Implementing finite state machines The PROLOG programming language (1) PROgrammation LOGique invented by Alain Colmerauer and colleagues at Marseille in early 70s. • A first introduction to PROLOG A PROLOG program is written in a subset of first order predicate logic. There are • Encoding finite state machines in PROLOG • constants naming entities • Recognition and generation with finite state – syntax : starting with lower-case letter 1 machines in PROLOG – examples: twelve, a, q 1 • variables over entities • Search spaces and how to traverse them – syntax : starting with upper-case letter 2 – depth-first – examples: A, This, twelve, – breadth-first • predicate symbols naming relations among entities – syntax: predicate name starting with a lower-case • Encoding finite state transducers in PROLOG letter with parentheses around comma-separated arguments – examples: father(tom,mary) , age(X,15) 1 starting with lower-case letter, a number or surrounded by single quotes 2 starting with upper-case letter or underscore: [A-Z ][a-zA-Z0-9 ]* 1 2 Some practical matters The PROLOG programming language (2) A PROLOG program consists of a set of Horn clauses: • Add a separate line with the word ”COMPLING” (and a return at the end) to your file • unit clauses or facts ~/.subscriptions . – syntax: predicate followed by a dot – example: father(tom,mary). • Start PROLOG (on the Ling. Dep. UNIX machines) • nonunit clauses or rules • Either at UNIX prompt: prolog – syntax: rel 0 :- rel 1 , ..., rel n . • Or in Emacs: M-x run-prolog – example: grandfather(Old,Young) :- • At the PROLOG prompt ( ?- ): father(Old,Middle), father(Middle,Young). • Exit PROLOG: exit. • Consult a file in PROLOG: [ filename ]. 3 Note: • Obtain more solutions: ; • Variables only have scope over a single clause; there • The SICStus manual is accessible from the course are no global variables. web page. • There is no explicit typing of variables or of the arguments of predicates. 3 The .pl ending is added automatically, but you need to use single quotes around the filename if it starts with a capital letter or contains special characters such as ”.” or ”–”. For example [’MyGrammar’]. or [’~/file-1’] . 3 4
Tracing a prolog query 1 1 Redo: grandfather(adam,claire) ? 3 2 Redo: father(ben,claire) ? 3 2 Exit: father(ben,chris) ? An example program: 1 1 Exit: grandfather(adam,chris) ? father(adam,ben). X = chris ? ; father(ben,claire). father(ben,chris). no grandfather(Old,Young) :- father(Old,Middle), father(Middle,Young). Tracing a query: ?- trace. {The debugger will first creep -- showing everything (trace) yes | ?- grandfather(adam,X). 1 1 Call: grandfather(adam,_218) ? 2 2 Call: father(adam,_675) ? 2 2 Exit: father(adam,ben) ? 3 2 Call: father(ben,_218) ? ? 3 2 Exit: father(ben,claire) ? ? 1 1 Exit: grandfather(adam,claire) ? X = claire ? ; 5 6 Encoding finite state automata in PROLOG representation PROLOG What needs to be represented? We need to represent: A finite state automaton is a quintuple • initial nodes ( Q, Σ , E, S, F ) with • final nodes • Q a finite set of states • edges • Σ a finite set of symbols, the alphabet • S ⊆ Q the set of start states Represented as facts in PROLOG: • F ⊆ Q the set of final states • initial( nodename ). • E a set of edges Q × (Σ ∪ { ǫ } ) × Q • final( nodename ). • arc( from-node , label , to-node ). 7 8
A simple example An example with two final states FSTN representation of FSM: FSTN representation of FSM: 1 1 d r c c o l o 0 6 5 4 2 u r 0 a b 3 3 2 PROLOG encoding of FSM: PROLOG encoding of FSM: initial(0). initial(0). final(1). final(1). arc(0,c,6). final(2). arc(6,o,5). arc(0,c,1). arc(5,l,4). arc(1,d,1). arc(4,o,2). arc(0,a,3). arc(2,r,1). arc(3,b,2). arc(2,u,3). arc(3,r,1). 9 10 Recognition with FSMs in PROLOG Tracing the two final state example | ?- test([c,d]). 1 1 Call: test([c,d]) ? test(Words) :- 2 2 Call: initial(_681) ? initial(Node), 2 2 Exit: initial(0) ? 3 2 Call: recognize(0,[c,d]) ? recognize(Node,Words). 4 3 Call: arc(0,_1805,_1806) ? ? 4 3 Exit: arc(0,c,1) ? recognize(Node,[]) :- 5 3 Call: traverse(c,[c,d],_1799) ? final(Node). 5 3 Exit: traverse(c,[c,d],[d]) ? 6 3 Call: recognize(1,[d]) ? recognize(FromNode,String) :- 7 4 Call: arc(1,_3686,_3687) ? arc(FromNode,Label,ToNode), 7 4 Exit: arc(1,d,1) ? traverse(Label,String,NewString), 8 4 Call: traverse(d,[d],_3680) ? 8 4 Exit: traverse(d,[d],[]) ? recognize(ToNode,NewString). 9 4 Call: recognize(1,[]) ? 10 5 Call: final(1) ? traverse(First,[First|Rest],Rest). 10 5 Exit: final(1) ? ? 9 4 Exit: recognize(1,[]) ? ? 6 3 Exit: recognize(1,[d]) ? ? 3 2 Exit: recognize(0,[c,d]) ? ? 1 1 Exit: test([c,d]) ? yes {trace,source_info} 11 12
Another example trace 9 4 Exit: arc(1,d,1) ? 10 4 Call: traverse(d,_1772,_3648) ? 10 4 Exit: traverse(d,[d|_3648],_3648) ? 11 4 Call: recognize(1,_3648) ? | ?- test(X). 12 5 Call: final(1) ? 1 1 Call: test(_206) ? 12 5 Exit: final(1) ? 2 2 Call: initial(_656) ? ? 11 4 Exit: recognize(1,[]) ? 2 2 Exit: initial(0) ? ? 7 3 Exit: recognize(1,[d]) ? 3 2 Call: recognize(0,_206) ? ? 3 2 Exit: recognize(0,[c,d]) ? 4 3 Call: final(0) ? ? 1 1 Exit: test([c,d]) ? 4 3 Fail: final(0) ? 5 3 Call: arc(0,_1778,_1779) ? X = [c,d] ? ; ? 5 3 Exit: arc(0,c,1) ? 1 1 Redo: test([c,d]) ? 6 3 Call: traverse(c,_206,_1772) ? 3 2 Redo: recognize(0,[c,d]) ? 6 3 Exit: traverse(c,[c|_1772],_1772) ? 7 3 Redo: recognize(1,[d]) ? 7 3 Call: recognize(1,_1772) ? 11 4 Redo: recognize(1,[]) ? 8 4 Call: final(1) ? 13 5 Call: arc(1,_5524,_5525) ? 8 4 Exit: final(1) ? 13 5 Exit: arc(1,d,1) ? ? 7 3 Exit: recognize(1,[]) ? 14 5 Call: traverse(d,_3648,_5518) ? ? 3 2 Exit: recognize(0,[c]) ? 14 5 Exit: traverse(d,[d|_5518],_5518) ? ? 1 1 Exit: test([c]) ? 15 5 Call: recognize(1,_5518) ? 16 6 Call: final(1) ? X = [c] ? ; 16 6 Exit: final(1) ? 1 1 Redo: test([c]) ? ? 15 5 Exit: recognize(1,[]) ? 3 2 Redo: recognize(0,[c]) ? ? 11 4 Exit: recognize(1,[d]) ? 7 3 Redo: recognize(1,[]) ? ? 7 3 Exit: recognize(1,[d,d]) ? 9 4 Call: arc(1,_3654,_3655) ? 13 14 Generation with FSMs in PROLOG ? 3 2 Exit: recognize(0,[c,d,d]) ? ? 1 1 Exit: test([c,d,d]) ? X = [c,d,d] ? ; 1 1 Redo: test([c,d,d]) ? generate :- 3 2 Redo: recognize(0,[c,d,d]) ? test(X), 7 3 Redo: recognize(1,[d,d]) ? write(X), 11 4 Redo: recognize(1,[d]) ? nl, 15 5 Redo: recognize(1,[]) ? fail. 17 6 Call: arc(1,_7394,_7395) ? 17 6 Exit: arc(1,d,1) ? 18 6 Call: traverse(d,_5518,_7388) ? 18 6 Exit: traverse(d,[d|_7388],_7388) ? 19 6 Call: recognize(1,_7388) ? 20 7 Call: final(1) ? 20 7 Exit: final(1) ? ? 19 6 Exit: recognize(1,[]) ? ? 15 5 Exit: recognize(1,[d]) ? ? 11 4 Exit: recognize(1,[d,d]) ? ? 7 3 Exit: recognize(1,[d,d,d]) ? ? 3 2 Exit: recognize(0,[c,d,d,d]) ? ? 1 1 Exit: test([c,d,d,d]) ? X = [c,d,d,d] ? 15 16
Recommend
More recommend