Xoandbit

Dzidrais avots

Apr 20th, 2016
27
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 6.21 KB | None | 0 0
  1. --
  2. -- Author: Pēteris Pakalns
  3. -- Apl.nr: pp15008
  4. --
  5. -- finite state nondeterministic automaton with epsilon transition
  6. -- lua dzidrais-avots.lua
  7. --
  8.  
  9. -- constants
  10. print_additional_info = true
  11. eps = "_eps"
  12. input_filename = "avots.txt"
  13.  
  14. -- ============================================================
  15. -- UTILITY functions
  16.  
  17. -- Split string into individual words ,
  18. -- eg. "asds asdf asdf asdf\n" => {"asds","asdf","asdf","asdf"}
  19. function getWordArray( str )
  20.     local W, i = {}, 1
  21.     while i do
  22.         local s, e = string.find(str, "%w+", i)
  23.         if s then
  24.             table.insert( W, string.sub(str, s, e))
  25.             i = e + 1
  26.         else i =nil end
  27.     end
  28.     return W
  29. end
  30.  
  31. -- Create set from array
  32. function getSet( array )
  33.     local Q = {}
  34.     for i,v in ipairs( array ) do Q[ v ]=true end
  35.     return Q
  36. end
  37.  
  38. -- return set union
  39. function setUnion( A, B )
  40.     A, B, R = (A or {}), (B or {}), {}
  41.     for i,v in pairs( A ) do
  42.         if ( v ) then R[ i ] = true end
  43.     end
  44.     for i,v in pairs( B ) do
  45.         if ( v ) then R[ i ] = true end
  46.     end
  47.     return R
  48. end
  49.  
  50. function setAppend( A, ...)
  51.     arg={...}
  52.     for key, B in ipairs(arg) do
  53.         B = B or {}
  54.         for elem,_ in pairs( B ) do
  55.             A[ elem ] = true;
  56.         end
  57.     end
  58. end
  59.  
  60. -- return set intersection
  61. function setIntersection( A, B )
  62.     A, B, R = A or {}, B or {}, {}
  63.     for i,v in pairs( A ) do
  64.         if ( v and B[ i ] ) then R[ i ] = true end
  65.     end
  66.     return R
  67. end
  68.  
  69. -- Check if set is empty
  70. function isEmptySet( A )
  71.     for i, v in pairs( A or {} ) do
  72.         if ( v ) then return false end
  73.     end
  74.     return true
  75. end
  76.  
  77. -- return set string representation
  78. function strSet( A )
  79.     local str, semicol="",false
  80.     str=str.." {"
  81.     for i,v in pairs( A ) do
  82.         if ( v ) then
  83.             str=str..((semicol) and "; "..i or " "..i )
  84.         end
  85.         semicol=true
  86.     end
  87.     str=str.."} "
  88.     return str
  89. end
  90.  
  91. -- return two element cortege set string representation
  92. function strCortegeSet( A )
  93.     str=""
  94.     for i, v in pairs( A ) do
  95.         for l, m in pairs( v ) do
  96.             for x,y in pairs( m ) do
  97.                 if ( y ) then
  98.                     str = str .. "("..i..";"..l.."):"..x.."; "
  99.                 end
  100.             end
  101.         end
  102.     end
  103.     return " { "..str:sub(1,-2).." } "
  104. end
  105.  
  106. -- #################################################
  107. -- Automaton functions
  108.  
  109. -- load finite state nondeterministic automaton with epsilon transition
  110. function load_data( filename )
  111.  
  112.     local file = io.open( filename, "r" )
  113.  
  114.     local Q = getSet( getWordArray( file:read() ) );
  115.     local E = getSet( getWordArray( file:read() ) );
  116.     local q0 = getSet( getWordArray( file:read() ) );
  117.     local F = getSet( getWordArray( file:read() ) );
  118.  
  119.     local delta = {}
  120.     for i,v in pairs( Q ) do delta[ i ] = {} end
  121.  
  122.     repeat
  123.         local line = file:read()
  124.         if line then
  125.             local word_array, let, next_state, state= getWordArray( line )
  126.             if ( #word_array < 2 ) then break end
  127.             if ( #word_array == 2 ) then
  128.                 state, let, next_state = word_array[ 1 ], eps, word_array[ 2 ];
  129.             else
  130.                 state, let, next_state = word_array[ 1 ], word_array[ 2 ], word_array[ 3 ];
  131.             end
  132.             if ( delta[ state ][ let ] == nil ) then delta[ state ][ let ] = {} end
  133.             delta[ state ][ let ][ next_state ] = true;
  134.         end
  135.     until (line==nil)
  136.  
  137.     file:close();
  138.  
  139.     return Q, E, delta, q0, F
  140. end
  141.  
  142. -- Check all state transitivity (eps)
  143. -- delta[ state ][ eps ] = TS( state )
  144. function explore_forward( delta, state )
  145.     local stack = {}
  146.     for to, check in pairs( delta[ state ][ eps ] or {} ) do
  147.         if ( check ) then table.insert( stack, to ) end
  148.     end
  149.  
  150.     while ( #stack > 0 ) do
  151.         local act_state = table.remove( stack )
  152.         for to, check in pairs( delta[ act_state ][ eps ] or {} ) do
  153.             if ( check ) then
  154.                 if ( not delta[ state ][ eps ][ to ] ) then
  155.                     delta[ state ][ eps ][ to ] = true;
  156.                     table.insert( stack, to );
  157.                 end
  158.             end
  159.         end
  160.     end
  161. end
  162.  
  163. -- epsilon
  164. function epsLetter( delta, q_now )
  165.     local q_upd = {}
  166.     for state,_ in pairs( q_now or {} ) do
  167.         setAppend( q_upd, delta[ state ][ eps ] )
  168.     end
  169.     setAppend( q_now, q_upd )
  170. end
  171.  
  172.  
  173. -- Returns if input word is accepted
  174. function deltaR( Q, E, delta, q_set, F, input )
  175.  
  176.     local q_now, q_next, last = setUnion( q_set, {} ), {}, 0
  177.  
  178.     if ( input==nil ) then input="" end
  179.  
  180.     for i=1,#input do
  181.  
  182.         local let = input:sub(i,i)
  183.         if ( isEmptySet( q_now ) or not E[ let ] ) then break end
  184.  
  185.         epsLetter( delta, q_now )
  186.  
  187.         for state,_ in pairs( q_now ) do
  188.             setAppend( q_next, delta[ state ][ let ] )
  189.         end
  190.  
  191.         q_now, q_next, last = q_next, {}, i;
  192.     end
  193.  
  194.     -- epsilon letter moves
  195.     epsLetter( delta, q_now );
  196.  
  197.     local good_states = setIntersection( F, q_now );
  198.  
  199.     if ( print_additional_info ) then
  200.         print("  Apstrādāts vārda prefiks : \""..input:sub( 1, last ).."\"\n");
  201.         print("     \t      Q(|w+eps|) =\t"..strSet( q_now ) )
  202.         print("     \tF inters. Q(|w|) =\t"..strSet( good_states ) )
  203.     end
  204.  
  205.     return not isEmptySet( good_states );
  206. end
  207.  
  208. -- READ DATA
  209.  
  210. local Q, E, delta, q_set, F = load_data( input_filename )
  211.  
  212. if ( print_additional_info ) then
  213.     print("\n########## Authomaton ################\n");
  214.     print("         Q =\t"..strSet( Q  ) )
  215.     print("  Alphabet =\t"..strSet( E  ) )
  216.     print("     delta =\t"..strCortegeSet( delta ) )
  217.     print("      {q0} =\t"..strSet( q_set ) )
  218.     print("         F =\t"..strSet( F  ) )
  219. end
  220.  
  221. -- UPDATE DATA
  222.  
  223. for i,v in pairs(Q) do explore_forward( delta, i ) end
  224.  
  225. if ( print_additional_info ) then
  226.     print("\n    delta\"eps =\t"..strCortegeSet( delta ) )
  227.     io.write("\n\n");
  228. end
  229.  
  230. -- User input
  231.  
  232. while ( true ) do
  233.     if print_additional_info then io.write("   Lūdzu ievadiet meklējamo vārdu(w): "); end
  234.     input = io.read()
  235.     io.write("\n\t\tAtbilde : "..(deltaR( Q, E, delta, q_set, F, input ) and "True" or "False" ).." ! \n\n");
  236. end
Advertisement
Add Comment
Please, Sign In to add comment