anchor.diff:      probability: double;
   } 
   
  -// works only for string of 2^n-1 length
   let recognize (strToParse: string) 
  -              (crl: Dictionary<NonTerminal * NonTerminal, (NonTerminal * double) list>)
  -              (srl: Dictionary<char, (NonTerminal * double) list>)
  -              (erl: NonTerminal list) 
  +              (complexRules: Dictionary<(NonTerminal * NonTerminal), (NonTerminal * double) list>)
  +              (simpleRules: Dictionary<char, (NonTerminal * double) list>)
  +              (epsilonRules: NonTerminal list) 
                 (nonterminals : NonTerminal [])
  -              S = 
  +              S 
  +              maxSearchLength = 
   
       let stringSize = String.length strToParse
   
       let strSizeExponent = (System.Math.Log (double stringSize)) / (System.Math.Log 2.) |> System.Math.Ceiling |> int
       let roundedSize = (1 <<< strSizeExponent) - 1
  -
  -
  -    // left-bottom triangle and diagonal of tMatrix and pMatrix are not used
  -    let tMatrix = new Map<NonTerminal, double [,]>(
  +    
  +
  +    let emptyMatrixOfSize n = Array2D.init n n (fun x y -> 0.)
  +    
  +    // bottom-left triangle and diagonal of tMatrix and pMatrix are not used
  +    // upper-right triangle of size (stringSize - maxSearchLength) is not used
  +    let tMatrix = new Map<NonTerminal, double [,]>
  +                        (
                               nonterminals 
  -                            |> Seq.map (fun x -> (x, Array2D.init (stringSize + 1) (stringSize + 1) (fun x y -> 0.))))
  -
  -    let pMatrix = new Map<NonTerminal * NonTerminal, double [,]>(
  -                            crl.Keys
  -                            |> Seq.map (fun x -> (x, Array2D.init (stringSize + 1) (stringSize + 1) (fun x y -> 0.)))) 
  +                            |> Seq.map (fun x -> x, emptyMatrixOfSize (stringSize + 1))
  +                        )
  +
  +    let pMatrix = new Map<NonTerminal * NonTerminal, double [,]>
  +                        (
  +                            complexRules.Keys
  +                            |> Seq.map (fun x -> x, emptyMatrixOfSize (stringSize + 1))
  +                        ) 
   
       let addToP nts (matrix: double [,]) (l1, m1, l2, m2) =
           let where = pMatrix.[nts]
  
positive.code:                                     
      let completeP where from1 from2 = 
          let completeOnePair (nt1, nt2) =
              addToP (nt1, nt2) (subMatrixMult tMatrix.[nt1] tMatrix.[nt2] from1 from2) where |> ignore
          pMatrix |> Map.toSeq |> Seq.map (fun (nts, _) -> completeOnePair nts) |> List.ofSeq |> ignore
  
      
      let rec compute l m =
  
negative.code: //    B -> 'b', 0.4
  //    B -> 'b', 0.4
  
      let printMatrix (matrix: double [,]) strLen searchLen =
          let rowLength = matrix.GetLength(0)
          let colLength = matrix.GetLength(1)
  
          for i in [0..rowLength-1] do
              for j in [0..colLength-1] do
                  if i <= strLen && j <= strLen && j > i && j-i <= searchLen then
                      printf "%.8f  " matrix.[i, j]
                  else
                      assert (matrix.[i, j] = 0.)
                      printf "----------  "
              printfn ""
          printfn ""
  
      let isAnswerValid (matrix: double [,]) strLen searchLen = 
          let rowLength = matrix.GetLength(0)
          let colLength = matrix.GetLength(1)
          if rowLength <> colLength || rowLength <> strLen + 1 then
              false
          else
              let notRealCell (i, j) =
                      i > strLen 
                      || j > strLen 
                      || j <= i 
                      || j-i > searchLen 
  
              [1..rowLength-1]
              |> List.map (fun i -> [1..colLength-1] |> List.map (fun j -> (i,j))) 
              |> List.concat
              |> List.filter notRealCell
              |> List.forall (fun (i, j) -> matrix.[i,j] = 0.)
  
      let check str searchLen = 
          let toCheck = recognize str crl srl erl nonterminals S searchLen
          assert (isAnswerValid toCheck (String.length str) searchLen)
          printMatrix toCheck (String.length str) searchLen 
  //        printfn "%.10f" toCheck |> ignore
  //        assert (abs(res - toCheck) < 1e-14) 
  
  //    check "abb"     0.032        2 |> ignore    
  //    check "aaabbcc" 0.0000524288 3 |> ignore
  
      check "abb"     2 |> ignore    
      check "abb"     3 |> ignore    
      check "aaabbcc" 3 |> ignore
  
  
      System.Console.ReadLine() |> ignore
      0