Advertisement
Guest User

Untitled

a guest
May 14th, 2019
130
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
F# 1.58 KB | None | 0 0
  1. type Re = Eps | Chr of char | Alt of Re*Re | Seq of Re*Re | Star of Re
  2.  
  3. let rec nullable =
  4.     function
  5.     | Eps | Star _ -> true
  6.     | Chr c -> false
  7.     | Alt(a,b) -> nullable a || nullable b
  8.     | Seq(a,b) -> nullable a && nullable b
  9.  
  10. let rec step (c:char) : Re -> list<Re> =
  11.     function
  12.     | Eps -> []
  13.     | Chr c' -> if c=c' then [Eps] else []
  14.     | Alt(a,b) -> List.append (step c a) (step c b)
  15.     | Seq(a,b) -> let steppeda = step c a |> List.map (fun a2 -> Seq(a2,b))
  16.                   let steppedb = if nullable a then step c b else []
  17.                   List.append steppeda steppedb
  18.     | Star a -> step c a |> List.map (fun a2 -> Seq(a2, Star a))
  19.  
  20. open System.Numerics
  21.  
  22. let stepState state c =
  23.     state |> List.collect (fun (re,n) -> step c re |> List.map (fun re' -> (re',n)))
  24.           |> List.groupBy fst |> List.map (fun (re,ns) -> (re,Seq.sumBy snd ns))
  25.  
  26. let parse re = Seq.fold stepState [re, BigInteger(1)]
  27. let count re = parse re >> List.filter (fst >> nullable) >> List.sumBy snd
  28.  
  29.  
  30. let n = 200
  31. let str = String.replicate n "a"
  32.  
  33. let a = Chr 'a'
  34. let sa = Star(a)
  35.  
  36. let re1 = Seq(sa, sa)
  37. assert (count re1 str = BigInteger(n+1))
  38.  
  39. let re2 = Seq(sa, Seq(sa, sa))
  40. assert (count re2 str = BigInteger((n+2)*(n+1)/2))
  41.  
  42. let re3 = Seq(sa, Seq(sa, Seq(sa, sa)))
  43. assert (count re2 str = BigInteger((n+3)*(n+2)*(n+1)/6))
  44.  
  45. let re4 = Star(Seq(a,sa))
  46. assert (count re4 str = pown (BigInteger 2) (n-1))
  47.  
  48. let re5 = Star(Alt(a, Seq(a, a)))
  49. let rec fib n a b = if n=0 then a else fib (n-1) b (a+b)
  50. assert (count re5 str = fib n (BigInteger 1) (BigInteger 1))
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement