anchor.diff:    | ExprShape.ShapeVar(v)                -> 1 + 1
     | ExprShape.ShapeCombination(o, exprs) -> 1 + (exprs |> List.map exprSize |> List.sum)
   
  -let examineAllRulesMetaData (rs: Rule List) (e: Expr): MetaData List = 
  +let examineAllRulesPositioned (rs: Rule List) (e: Expr): MetaData List = 
     let rec rcr (exp: Expr) (meta: InputMetaData): MetaData List = 
       let immediatelyConstructedExpressions = rs |> List.collect (fun r -> applyRule r exp |> List.map (fun _ -> meta, r)) 
       let constructedExpressionsByChildren =
  
positive.code: 
  type InputMetaData = RulePosition
  
  type MetaData = InputMetaData * Rule
  
  let private zeroMetaData: InputMetaData = 0
  
  
negative.code:           let exprsExpressions = (([], meta + 1), exprs) ||> List.fold (fun (ms, idx) e  -> (rcr e idx) :: ms, idx + exprSize e)
            ExprShape.RebuildShapeCombination(o, fst exprsExpressions |> List.rev)
    rcr e zeroMetaData
  
  type RuleWeight = double // should be normalized between 0 and 1
  type RuleFeature = RuleWeight
  
  let ZERO_FEATURE = 0.
  
  let heuristicOptimizer (threshold: int) (rs: (Rule * RuleFeature) list) (initProgram: Expr): Expr = 
    let rand = new System.Random()
    let ruleFeaturesMap = rs |> List.map (fun (r, f) -> snd r, f) |> Map.ofList
    let filteredRules = rs |> List.filter (fun (r, f) -> f <> ZERO_FEATURE) |> List.map fst
    let tapp = tic()
    tapp.Stop()
    let tmatch = tic()
    tmatch.Stop()
    let mainLoop (currentProgram: Expr) (rule: MetaData): Expr = 
      tapp.Start()
      let result = applyRuleAtParticularPosition currentProgram rule
      tapp.Stop()
      result
    let chooseRule (currentProgram: Expr): MetaData option = 
      tmatch.Start()
      let allApplicablePositionedRules = examineAllRulesPositioned filteredRules currentProgram 
      let rulesCount = allApplicablePositionedRules |> List.length
      tmatch.Stop()
      // TODO use weigths to make it weighted random selection, however the prefiltering based on
      // zero weights seems to be sufficient for the moment.
      if rulesCount = 0 then
        None
      else
        let randomIndex = rand.Next(rulesCount)
        Some (allApplicablePositionedRules.[randomIndex])
    let result = 
      fixPoint threshold (fun currentProgram -> 
        match chooseRule currentProgram with
        | Some(rule) -> mainLoop currentProgram rule
        | None       -> currentProgram
      ) initProgram
    toc tapp
    toc tmatch
    result
  
  let rec inliner (exp: Expr): Expr = 
    match exp with 
  